例如,为什么以下内容不起作用?
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/