我有这段代码:
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()
,整个代码都有效,我不明白为什么。方法测试期望(T y)
位于T extends Date
并实现List
,但它适用于gt.test(new Date())
。
答案 0 :(得分:16)
当您实例化时:
CREATE TRIGGER PrecioCompra After Insert or Update ON "Compra"
您使用GenericTest gt = new GenericTest()
类型的原始版本。这意味着GenericTest
类型将被第一个绑定(在您的情况下为T
)替换。这就是为什么Date
的方法合约具有GenericTest#test()
参数,而不是Date
参数的原因。
请注意,除第一个绑定外,每个绑定都必须是一个接口。只有第一个绑定可以成为一个类。这样做的原因是它不可能有类型,它继承了超过一个超类。
因此,由于只有第一个参数是一个类,因此您无法切换类型参数,并且以下类定义将无效:
List
答案 1 :(得分:0)
错误是因为在编译时使用通用代码进行了更严格的类型检查,并且在给定的代码中使用了参数化类型。
正如在问题中提到的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
}
}
答案 2 :(得分:-2)
如果创建没有泛型参数的泛型类实例,编译器会发出警告,并且不再控制已创建实例的使用情况。至于为什么代码在没有声明泛型类型的情况下工作 - 因为在这种情况下T被假定为Object,那就是任何类型都是好的