为什么以下代码干净地编译而没有任何警告,即使是xlint:all?
class A<V> {
public V v;
public <V> A() {
}
public static <V> A<V> create() {
return new A<V>();
}
}
public class FooMain {
public static void main(String args[]) {
A.create().v = 5;
A.create().v = "a string";
}
}
Run Code Online (Sandbox Code Playgroud)
运行:
javac -Xlint:all src/FooMain.java
Run Code Online (Sandbox Code Playgroud)
导致干净的编译没有任何警告(未选中等).A在第一行创建的泛型类实例的类型参数化是什么,第二行是什么?编译器如何确定类型?通过查看r值的类型?
在这两个语句中,编译器没有足够的信息来推断 的类型参数V。当发生这种情况时,它默认为V的上限,即Object。
这些分配是有效的,因为 和 都可5分配"a string"给Object。
A.create().v我们可以通过尝试将isObject分配给更具体的类型来显示 is 的类型:
Integer i = A.create().v; // Type mismatch: cannot convert from Object to Integer
Run Code Online (Sandbox Code Playgroud)
即使我们先分配一个更具体的类型(赋值表达式的结果是分配变量的类型),错误也是一样的:
Integer i = (A.create().v = 5); // same error
Run Code Online (Sandbox Code Playgroud)
请注意,“类型见证”可用于显式指定泛型类型参数(如果未推断出它们):
Integer i = A.<Integer>create().v; // valid
A.<String>create().v = 5; // incompatible types
A.<Integer>create().v = "a string"; //
Run Code Online (Sandbox Code Playgroud)
这些是为了演示编译器行为而设计的示例,但类型见证有时很有用,例如:
static void m(List<String> list) { }
public static void main(String args[]) {
m(Collections.emptyList()); // error
m(Collections.<String>emptyList()); // valid
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
146 次 |
| 最近记录: |