Java在编译期间,所有的泛型信息都会被擦掉,反编译后会多了一个最后一行的签名文件Signature,保存到就是泛型的信息。那么之后JVM之后又是如何来判断我所需要的类型方法或者说提供的类型参数?
public class Pair <T>{
private T first;
private T second;
public Pair(T first, T second) {
this.first = first;
this.second = second;
}
}
class Test
public static void main(String[] args){
Manager CEO = new Manager("CEO", 5000, 2002, 1, 1);
Manager CFO = new Manager("CFO", 6000, 2000, 1, 9);
Pair<Manager> managerPair = new Pair<>(CEO, CFO);
}
就拿这个方法来说,类型擦除后就是
public class Pair {
private Object first;
private Object second;
public Pair(Object first, Object second) {
this.first = first;
this.second = second;
}
}
class Test
public static void main(String[] args){
Manager CEO = new Manager("CEO", 5000, 2002, 1, 1);
Manager CFO = new Manager("CFO", 6000, 2000, 1, 9);
Pair managerPair = new Pair(CEO, CFO);
}
它之后又是怎么创建我需要的类型参数的?
下面为什么不能通过,类型消除后Pair<manager>变成了Pair原始类型,那么相应的里面的实例字段也变成Object类型,编译后虽然类型消除了变成原始类型,但后面虚拟机会通过某种方式转换成Manager,这样岂不是和强制类型转换一样;那么既然用了强制类型转换,我就有第二种想法,类型消除后,lowlyEmployee是能转换成Object,然后Object转换成Manager,这两种都用到了强制类型转换,为什么后者不允许.........(题主刚入门,当然这说法是建立在如果我想的是正确的情况下,有点乱,放下代码示意图,如果类型消除真是这样,那么岂不是Pair<T> pair = public Pair(T first, T second)方法里无论传入的是T的子类对象还是父类对象都应该可以的吗?)
Manager manager = new Manager("CEO", 5000, 2002, 1, 1);
Object first = manager;
Manager M1 = (Manager) first;
Employee lowlyEmployee = new Employee("zhang san", 1000, 2001, 2 ,1);
Object second = lowlyEmployee;
Manager M2 = (Manager) second;
public static void main(String[] args) {
Employee lowlyEmployee = new Employee("zhang san", 1000, 2001, 2 ,1);
Manager manager = (Manager) lowlyEmployee;
Pair<Manager> pair = new Pair<Manager>(lowlyEmployee, lowlyEmployee); //error
//Pair<Manager> pair = new Pair<Manager>(manager, manager); ok
//Pair<Employee> pair = new Pair<Employee>(manager, manager); ok
}
显然你没理解泛型的作用。
JVM在运行时不需要判断类型。直接强制转换,为什么呢?因为编译时确保类型一致性。
你的例子举错了。
Pair<Manager> managerPair = new Pair<>(CEO, CFO);
这行代码不能说明泛型的作用。
泛型的作用是jvm在执行时能直接强转。
比如
List<String> list
,在执行时能直接String a = list.get(0);
不用担心强转出错。因为类型擦除,
list.get(0)
返回的是Object,为什么能直接强转为String?因为编译器做了“安检”工作。至于那行为什么报错,鼠标放在错误上idea就会告诉你为什么错了。类型不匹配。这也是编译器在泛型中起的作用。