[英]Java Generics: Multiple Bounds
我有这个代码:
public class Test {
public static void main(String[] args) {
Test t = new Test();
t.callTest();
}
public void callTest() {
GenericTest gt = new GenericTest<Date>(); // this line don't compile
gt.test(new Date());
}
class GenericTest<T extends Date & List> {
T x;
public void test(T y) {
System.out.println(x.toString());
}
}
}
我明白为什么new GenericTest<Date>()
不能编译,那是因为 Date 没有实现 List 接口,但是如果我实例化GenericTest gt = new GenericTest()
没有泛型,整个代码工作,我不明白为什么。 方法 test 期望(T y)
其中T extends Date
并实现List
,但它适用于gt.test(new Date())
。
当你像这样实例化时:
GenericTest gt = new GenericTest()
您使用GenericTest
类型的原始版本。 这意味着T
类型将被替换为它的第一个绑定(在您的情况下为Date
)。 这就是为什么GenericTest#test()
的方法契约有一个Date
参数,而不是一个List
参数。
请注意,除了第一个边界外,每个边界都必须是一个接口。 只有第一个边界可以是一个类。 这样做的原因是不可能有从多个超类继承的类型。
因此,由于只有第一个参数是类,因此您将无法切换类型参数,并且以下类定义将无效:
class GenericTest<T extends List & Date> { }
错误是因为在编译时使用泛型代码进行了更强的类型检查,并且在给定的代码中使用了参数化类型。
正如问题中提到的GenericTest gt = new GenericTest()
编译和执行,那只是因为这里调用了 toString() 方法。 如果它是某个 List 接口方法,那么执行时会出现 ClassCastException。 让我们说 size()。
class GenericTest<T extends Date & List> {
public void test(T y) {
System.out.println(y.size()); // ClassCastException
}
}
如果您创建一个没有泛型参数的泛型类实例,编译器会发出警告并且不再控制所创建实例的使用。 至于为什么代码在没有声明泛型类型的情况下工作 - 因为在这种情况下,T 被假定为 Object,任何类型都是好的
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.