[英]Type inference in generic method & generic class
无法理解Java中的泛型编程。
我读了一些关于它的教程,但仍然很困惑,特别是当事情变得复杂时。
谁能解释一下这个例子中发生了什么?
import java.util.Date;
public class Test1 {
public static void main(String[] args) {
P<Cls> p = new P<>(); //<1> //I expect a ClassCastException here, but no. Why? //How does the type inference for class P<E> work?
System.out.println(p.name); //it prints
// System.out.println(p.name.getClass());//but this line throws ClassCastException //why here? why not line <1>?
test1(p);//it runs
// test2(p);//throws ClassCastException//What is going on in method test1&test2?
//How does the type inference for generic methods work in this case?
}
public static<T> void test1(P<? extends T> k){
System.out.println(k.name.getClass());
}
public static<T extends Cls> void test2(P<? extends T> k){
System.out.println(k.name.getClass());
}
}
class P<E>{
E name = (E)new Date();//<2>
}
class Cls{}
P<Cls> p = new P<>();
请记住,Java通过擦除来实现泛型,这意味着P
的构造函数实际上并不知道E
在运行时是什么 。 Java中的泛型纯粹是为了在编译时帮助开发人员。
这意味着当您创建一个new P<>()
,会创建一个new Date()
, 但它实际上并没有转换为任何特定类型,因为运行时对E
没有任何了解 。 E
在运行时不存在,只要P<E>
类而言。 name
只是一个内部有Date
的Object
引用。 但是,每当您编写以运行时环境需要知道它是特定类型(在本例中为Cls
)的方式使用name
代码时,编译器会在不告诉您的情况下将强制转换插入该类型。
p.name.getClass()
被编译为((Cls)p.name).getClass()
,它将创建一个类((Cls)p.name).getClass()
异常。 test2()
指定非泛型的类型约束( extends Cls
)。 因此,它对p.name.getClass()
调用同样被转换为((Cls)p.name).getClass()
。 另一方面:
System.out.println(p.name)
实际上与System.out.println((Object)p.name)
相同,因为println
是一个采用object
的非泛型方法。 test1(p.name)
类似。 因为运行时实际上并不知道T
是什么类型,所以它在调用getClass()
之前基本上将p.name
强制转换为Object
。 换句话说,这是你的代码,因为它实际上被编译:
class P{
Object name = new Date();
}
public static void main(String[] args) {
P p = new P();
System.out.println(p.name);
System.out.println(((Cls)p.name).getClass());
test1(p);
test2(p);
}
public static void test1(P k){
System.out.println(k.name.getClass());
}
public static void test2(P k){
System.out.println(((Cls)k.name).getClass());
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.