java泛型的魔性
2019-03-12 本文已影响0人
炫迈哥
1. 原生类型能赋值给任何类型的泛型
如: List可以赋值给List<?> List<Object> List<Long> 等
因为List这种原生类型是老版本java兼容而保留的, 要想与新的泛型兼容,必须要能强制转化,如:
- 老版本的代码
public class A {
public static List test(){
...
}
public static void main(String[] args){
List a = test();
}
}
- 新版本代码
public class A {
public static List test(){
...
}
public static void main(String[] args){
List<String> a = (List<String>)test();
}
}
2.List<?>
他表示使用者根本不关心泛型内容, 与List<Object>有本质区别
所以,编译器不会允许往里面设置任何值, 获取值是可以的
tips: 任何类型泛型都可以赋值给 <?>
3.任何类型的泛型相互之间均可以通过原生泛型作为媒介转换
List<Long> r = null;
List<String> s = Arrays.asList("1", "2");
List c = s;
r = c;
神奇的将 List<String>转换成了List<Long>,编译器也不会报错
- java编译器在运行时会泛型擦除, 所有的T ,E这些泛型均直接用Object类型表示
所以 :
System.out.println(r.get(0));
是可以正常打印输出的! 为什么 ? 1. r.get(0)这段代码对编译器来说只是把值作为Object类型拿出来 2. System.out.println 接受的参数也是Object类型
- 当获取值有指定类型接收变量时, 会直接报类型转换错误
Long value = result.getValue(); // 以long类型接收, 因为值本来是字符串,所以无法转换成long,报错
- 链式调用getClass方法报类型转换异常
Object first = result.getValue();
System.out.println(first.getClass()); // 正常打印
System.out.println(result.getValue().getClass()); // 报类型转换异常
查看class文件 System.out.println(((Long)s.getValue()).getClass()); 链式调用时会先进行类型转换