问题:集合元素类型
•
•
1:不能在编译时被检测
•
•
2:分派时必须被强制转换
•
还是那个原则,告诉编译器你的collection中需要什么类型,编译器为你完成一切(类型检查,转型等)。
看代码:
•
ArrayList<String> a = new ArrayList<String>();
•
a.add("hello");
•
System.out.println(a.get(0));
•
//output:Hello
•
System.out.println(strArrayList.getClass());
•
//output:class java.util.ArrayList
反编译后代码:
•
ArrayList a = new ArrayList();
•
a.add("hello");
•
System.out.println((String)a.get(0));
•
System.out.println(a.getClass());
实际上包括转型等都是javac帮我们做了。
从上面的代码中我们还能看出问题:看
紫色
标记的代码,我们打印a的类型,该变量在声明的时候是ArrayList<String>类型
的,我们的头脑里会认为打印出的应该是“class java.util.ArrayList<String>”,可实际打印出的信息告诉我们
collection中的元素的类型信息被丢弃了。也就是说ArrayList<Integer>和ArrayList<String>本不该是同一类型,不过我们
看到的实际情况却是他们是同一类型。由于java中的generic只是在compiler一级得到支持,在jvm一级是不知道有generic这
回事的。
•
•
•
一个参数化的类或接口声明定义一个集合类型,其中的每个元素都可能是该类型参数的一个实例化片段。所有参数化类
•
型在运行时共享同样的类或接口。如:
•
Vector<String> x = new Vector<String>();
•
Vector<Integer> y = new Vector<Integer>();
•
return x.getClass() == y.getClass();
•
结果为:
true
•
注:1、有了泛型的存在,在取元素的时候不用进行强制类型转换,系统会在编译时进行类型检测!
2、指定的类型不能是原始类型!(目前不被支持)
3、假设A是B的子类,我们声明了一个泛型声明G<A>和G<B>,此时不能认为G<A>是G<B>的一个子类型!这会引发一些问题
3、在定义集合等时声明了类或接口的类型则限制了该集合能加入的类型!如在一个声明为Integer类型的集合
•
中加入String类型,则提示:
•
The method add(Integer) in the type of ArrayList<Integer> is not applicable for the arguments (String)