在this topic我遇到了侮辱类型。
问题1。 Java中隐式类型的强大防御是什么?它是非正式的概念?我可以手动定义隐式类型吗?所有隐式类型是否相同都是真的吗?什么是编译器的隐式类型?
以下代码示例:
List<? extends Number> nums= new ArrayList<Integer>();
nums.add(3);//error
我知道我们可以将nums
引用分配给ArrayList<Double>
。
问题2。在此上下文中,? extends Number
是隐式类型,由CAP#1
定义。编译器确实知道只有null
是这种隐式类型的实例吗?
答案 0 :(得分:2)
正确的术语是捕获通配符。编译器在内部将泛型类型的通配符实例化转换为捕获通配符。捕获表示类型参数的特定未知类型。当然,这种特殊的未知类型是通配符所表示的类型族的成员。
请注意,由于可以通过通配符实例化表示许多不同类型,我们说通配符表示参数化类型的不同实例化的族。
我可以手动定义隐式类型吗?
匿名类型变量?不。那是由内部编译器创建的。您可以这么说,您正在指示编译器创建一个匿名类型参数,该参数将替换使用的通配符。
所有隐式类型都是一样的吗?
没有。如果您使用两次作为不同类型说List<? extends Number>
,则它们都会生成不同的匿名类型,即CAP#1 extends Number
和CAP#2 extends Number
。
编译器的隐式类型是什么?
我不明白这些问题。
编译器确实知道只有
null
是这种隐式类型的实例吗?
添加null
的原因是由于null
是任何类型引用的有效值。因此,无论通配符表示的实际类型参数如何,都会很乐意接受值null
。
答案 1 :(得分:0)
您不能将任何内容放入使用扩展通配符声明的类型(除外),用于值null
,属于每种引用类型
List<Integer> ints = Arrays.asList(1,2,3);
List<? extends Number> nums = ints;
nums.add(null); // ok
assert nums.toString().equals("[1,2,3,null]");
通常,如果结构包含格式为? extends E
的元素,我们就可以获得
结构之外的元素,但我们不能将元素放入结构中(null
除外)。放在
元素进入结构我们需要super
通配符:
List<Number> nums = new ArrayList<Number>();
nums.add(2);
nums.add(3.14);
List<? super Integer> ints = nums;
ints.add(3);
ints.add(null);
结果:[2, 3.14, null]