Mic*_*yen 7 java generics compiler-errors compilation
我们已经开始在使用泛型的代码上编译错误,并且在Java 6下成功编译.这是一个简单的类来重现:
class Test {
static class Foo<T> {
T t;
Foo(T t) { this.t = t; }
T get() { return t; }
}
static class Bar extends Foo<Long> {
Bar(Long t) { super(t); }
}
static class Foobar<N extends Number> extends Bar {
Foobar() { super(5L); }
}
public static void main(String[] args) {
Bar bar = new Bar(0L);
Long b = bar.get(); // This works
Foobar foobar = new Foobar();
Long fb = foobar.get(); // This generates a compile time error
}
}
Run Code Online (Sandbox Code Playgroud)
产生的错误是:
Test.java:26: error: incompatible types: Object cannot be converted to Long
Long fb = foobar.get(); // This generates a compile time error
Run Code Online (Sandbox Code Playgroud)
有人有什么想法吗?
这是因为Foobar没有任何类型参数是原始类型。原始类型没有通用能力,因此在这种情况下,原始类型Foobar扩展Bar了原始类型Foo。原始类型使用其参数的上限,因为它们是在擦除后以这种方式编译的,并且编译器没有类型参数来安全地插入强制转换。
在 的情况下Foo,该上限为Object。这会导致Foo.get()return Object,因此Bar.get()返回Object,因此也Foobar.get()返回。显然,如果没有显式强制转换Object,编译器不会强制转换。ObjectLong
相反,参数化类型Foobar<N>extendsBar扩展了参数化类型Foo<Long>。编译器现在可以使用泛型,因此它会看到Foo<T>.get()具有 type T、Foo<Long>.get()具有 type Long、Bar.get()具有 type Long、最后Foobar<N>.get()具有 type Long。
这意味着您应该foobar如下声明:
Foobar<...> foobar = new Foobar<...>();
Run Code Online (Sandbox Code Playgroud)
参数的类型是什么并不重要foobar,只要它存在即可。它甚至可以是通配符?。
| 归档时间: |
|
| 查看次数: |
110 次 |
| 最近记录: |