作者回复:
Effective Java里总结出过一个简单的抛弃这些概念的规则:producer-extends, consumer-super(PECS),想让List作为生产者提供数据,就用extends,想让List作为消费者放入数据,就用super。
作者回复:
返回值是这种类型,你提到强转,我的理解是map的value类型。确实,这时候如果知道map的value具体是什么类型,就需要强转。当然,如果不确定,可以instanceof判断一下。
作者回复:
类型擦除是指运行时无法获取范型信息。范型仅仅是能用在编译期对引用类型(对应你的问题,不是具体对象的类型)进行类型检查,运行的时候,范型信息就被擦除了。
作者回复:
我在视频里提过一嘴,Java 的范型就做了两件事情
1)根据各种语法元素,让编译器知道一个 Object 引用允许指向什么类型的对象。什么上界下界,协变逆变,都是细节。最终的目的就是判断,一个范型的引用是不是可以指向某个具体类型的对象,或者一个范型的参数,是否可以接受某个具体的类型的引用作为实参。
2)检查完之后,就是强制类型转换。 Java 编译器会在生成的字节码里,帮我们加上强制类型转换的语句,省去我们自己写强制类型转换了。而且通过1)的检查,也“尽力”避免了出现ClassCastException的可能。
汇成一句话就是:
“编译期类型检查,运行时类型擦除”
你如果去看 Java 编译出来的带范型的类文件的字节码,会发现编译器添加的强制类型转换相关的操作
P.S. :Java 的范型是后面加上去的,有些设可能是处于妥协。但是在我看来,也是够用了。