java - 如果 Java String 扩展了 Object 那么为什么不能将它传递给 <?扩展对象> 类型

标签 java string compiler-errors extends

例如,为什么以下内容不起作用?

Map<String, ? extends Object> table = new HashMap<>();
table.put("K", "V"); //Error V cannot be applied to ? extends String.

但是 String 必须扩展 Object,为什么上面会抛出编译错误?

我得到的 IntelliJ 错误是

Wrong 2nd Argument Type. Found 'java.lang.String'required: '? extends java.lang.Object'

但是下面的工作:

Map<String, ? super Object> table = new HashMap<>();
table.put("K", "V"); //Error V cannot be applied to ? extends String.

现在上面的内容真的很奇怪。下界如何在 Object 类上工作?

我是说没有

? super Object

意思是“Unknown that is superclass of Object”?

AFAIK 对象位于 Java 类层次结构的根部。

最佳答案

因为? extends Object 并不意味着“任何扩展 Object 的类型”。它的意思是“一些特定的类型,我们不知道它是什么,只要它扩展了 Object”。差别很小,但很重要!

下面的代码编译完全没问题:

Map<String, Integer> stringToInteger = new HashMap<>();
Map<String, ? extends Object> stringToWildcard = stringToInteger;

编译是有道理的。 stringToWildcard 是一个映射,其值为“某种类型...只要它扩展了 Object”——而 Integer 是一种扩展对象的类型。

因此,考虑到这一点,想象一下您的 table.put("K", "V") 是否有效。我们可以这样做:

Map<String, Integer> stringToInteger = new HashMap<>();

Map<String, ? extends Object> stringToWildcard = stringToInteger;
stringToWildcard.put("K", "V");

Integer value = stringToInteger.get("K");

这将导致最后一行出现 ClassCastException,因为字符串“V”无法转换为整数。

相反,编译器将不允许 table.put("K", "V")。它告诉你的是:“嘿,这个值需要是某种特定的类型。我不知道那个类型是什么,除了它扩展了 Object。但我不能让你放入一个 String,因为我不知道不知道那个类型是不是字符串。”

关于java - 如果 Java String 扩展了 Object 那么为什么不能将它传递给 <?扩展对象> 类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43618339/

相关文章:

java - 将字符串转换为字符串文字

compiler-errors - GLSL编译器选择了错误的重载函数?

Java套接字编程。如何在后台等待服务器响应?

java - 带有单选按钮的对话框不适用于 onClick()

string - 在字符串上随机化大小写的最快方法

compiler-errors - Lisp 非法函数调用,

android - 错误: Cannot find symbol variable

java - 何时使用抽象类或接口(interface)?

java - 为什么执行时没有出现Error "Add unimplemented methods"(Eclipse)

php - 数组到字符串转换错误