所以,我正在查看 Oracle Java 教程,特别是这段代码;
List<EvenNumber> le = new ArrayList<>();
List<? extends NaturalNumber> ln = le;
ln.add(new NaturalNumber(35)); // compile-time error
可以找到here .据我了解(如果我错了请纠正我)上面的代码将无法工作,因为编译器不知道 ln
引用 EvenNumbers 的列表,因此这可以防止您意外添加任何可能是列表元素的父类(super class)型的对象。如果是这种情况,那么如果您有类似 Number num = new Integer(6);
的声明,那为什么会这样呢?如果您像这样编写 if 语句,编译器能够正确地确定 num 是一个 Integer 对象;
if (num instanceof Integer) {...}
?
我想我的问题是,编译器如何确定 num
指的是 Integer
第二个例子中的对象,但无法确定 ln
指的是 List<EvenNumber>
第一个例子中的对象?
最佳答案
一般来说,编译器能够确定很多事情,并在优化代码时使用它的观察结果。
然而,Java 是statically and strongly类型语言和编译器在类型安全方面没有自由。
1) 添加到 ln
列表是被禁止的,因为人们不知道它应该包含哪种类型的元素。在您的示例中,此规则阻止将列表置于无效状态。
2) “...编译器能够正确确定 num 是一个整数...”
不正确,编译器不能确定它(尽管如果 Java 是弱类型语言它可以)。
3) num instanceof Integer
这是在运行时评估的,而不是在编译时评估的。但是,以下会产生编译时错误:
num instanceof 字符串
因为 Number
永远不可能是 String
。
关于Java 泛型和 instanceof 关键字,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32813813/