PDF 课件和源代码下载地址:
https://gitee.com/geektime-geekbang/LetsJava
作者回复: ✅✅
作者回复: 这都是编译器做的移花接木的工作。Java中的范型是编译期做的,范型类型并不能带到运行期。也就是说,如果反编译class文件的字节码的话,是看不到范型的信息的。举个例子,下面的源代码getData方法使用了范型: public class ABC { public static void main(String[] args) { ABC abc = new ABC(); String s = abc.getData(new Object()); System.out.println(s); } public <T> T getData(Object data){ T t = (T)data; System.out.println(t.hashCode()); return t; } } 反编译其生成的class文件,其实得到的反编译后的源代码是下面这样的: public class ABC { public ABC() { } public static void main(String[] args) { ABC abc = new ABC(); String s = (String)abc.getData(new Object()); System.out.println(s); } public <T> T getData(Object data) { System.out.println(data.hashCode()); return data; } } 已经完全没有了泛型的信息。
作者回复: 是的
作者回复: ✅✅
作者回复: 对的~
作者回复: 可以参见我的两篇FAQ https://xie.infoq.cn/article/2b74611c9d2f1750778ad1458 https://xie.infoq.cn/article/fe1b6695165e1df18e91e9901
作者回复: 强制类型转换和类型擦除是一起发生的。类型擦除就是把泛型信息删除了。
作者回复: List<Object> causeError = ret; 这就是要用到泛型的逆变协变的地方。详见FAQ https://github.com/geektime-geekbang/LetsJava/blob/master/FAQ/04%E7%AB%A0-%E8%8C%83%E5%9E%8B%E5%BC%95%E7%94%A8%E7%9A%84%E9%80%9A%E9%85%8D%E7%AC%A6%E5%86%8D%E8%A7%A3.md