看书的时候看到“泛型类被它的所有实列所共享”,不是很理解这句话。
书上给出的解释如下:
以下面的方式创建list1和list2:
ArrayList<String> list1 = new ArrayList<>();
ArrayList<Integer> list2 = new ArrayList<>();
尽管在编译的时候ArrayLIst<String>和ArrayList<Integer>是两种不同的类型,但是,在运行时只有一个ArrayList类加载到JVM中。
为什么两个ArrayList类最终只有一个加载到JVM中去?请指教,谢谢
我感觉从CLASS字节码文件上更好理解,ClASS对应的是具体的一个类。
ArrayList 在JRE中的定义类只有一个ArrayList<Object>,因此,你见过JRE中有ArrayList<String>和 ArrayList<Integer>这两个类么?
String和Integer只是ArrayList<Object>实例化时的两个参数而已,
再准确一点
ArrayList<String> list1 = new ArrayList<>();
ArrayList<Integer> list2 = new ArrayList<>();
只是两个对象,而不是两个类(JVM不可能动态生成一个类的),JVM 加载的是类CLASS文件(实实在在的类),为不是这两个值,他们指向的都是ArrayList<Object>类的class文件
看完你的回复,我好像知道我的理解偏差出现在哪里了。
我以前的理解是,当使用
ArrayList<String> list1 = new ArrayList<>();
ArrayList<Integer> list2 = new ArrayList<>();
实例化两个对象时,JVM只会加载一次ArrayList类。
==========================================================
现在我的理解是,当使用上述的语句实例化两个对象时,两个泛型使用的都是ArrayList类,但是它会在JVM中加载两次,是这样吗?
因为泛型本质上是:一个类 ArrayList 他有一个类型参数String
泛型只是这个类的一个参数.不是这个类本身.
所以这个地方还有一个问题: 泛型基类的静态泛型成员在不同的泛型子类中.是不是同一个对象.
所以你说的书上的这句话如果是对的.那JAVA的泛型实现就问题很大.原因就是上面的问题
java的泛型使用了“擦除法”来实现,简单点理解就是:ArrayList<String>和 ArrayList<Integer>仅在编译期有类型上的区别,而在运行时,它们都是ArrayList<>类型(空缺的类型参数是Object)。
这一点和C#与.net中的泛型差得远。
“泛型类被它的所有实列所共享”
是说:ArrayList这个泛型类在运行时被它的实例ArrayList<String>和ArrayList<Integer>共享。
“为什么两个ArrayList类最终只有一个加载到JVM中去”
》》
JVM是运行时环境,它只认识ArrayList<Object>类。