1.泛型与原生态类型的概念
泛型就是带一个或多个类型参数E的类或者接口,而原生态类型是不带任何实际类型的泛型,例如List是原生态类型,List < String >或者List< E >是泛型。
2.泛型的作用
泛型是在jdk1.5之后添加的。
举个例子:
public class test {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add(new Integer(2));
String s = (String) list.get(0);
}
}
就会在运行时抛出
Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
at wqeqw.test.main(test.java:10)
然而添加了泛型
public class test {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList();
list.add(new Integer(2));
//不用显式声明类型转换
String s = list.get(0);
}
}
就会在编译时抛出
The method add(String) in the type ArrayList<String> is not applicable for the arguments (Integer)
而且不用显式声明类型转换。
总结:泛型的作用是将jdk1.5以前在运行期间容易发生问题的强制类型转换问题提前到编译期间检查。
3.List<Object>和List的区别
先看一个例子:
public class test2 {
public static void main(String[] args) {
List<String>lists= new ArrayList<String>();
test2.add(lists, 123);
String string = lists.get(0);
}
public static void add(List list,Object o) {
list.add(o);
}
}
这里依然会发生强制转换的问题,原因是List< String >是List的子类,借此,可以通过多态这种小把戏,能让List< String >做出“出格”的行为。
而List< String >并不是List< Object >的子类,可以在编译期间就检查,防止做出小把戏。
//将List换成List<Object>
public static void add(List<Object> list,Object o) {
list.add(o);
}
就会在编译期间发现小把戏:
The method add(List<Object>, Object) in the type test2 is not applicable for the arguments (List<String>, int)
总结:List原生类型避免了类型检查,失去安全性,后者明确告诉编译器能够持有任何类型的对象。
4.List<?>和List的区别
?是无限制通配符类型
下面来看一个例子:
public class test3 {
public static void main(String[] args) {
Set<String>sets1= new HashSet<String>();
test3.add(sets1);
test3.add2(sets1);
}
public static void add(Set s) {
s.add(1);
}
//The method add(capture#1-of ?) in the type Set<capture#1-of ?> is not applicable for the arguments (int)
public static void add2(Set<?> s) {
s.add(1);
}
}
这里在List< String >中添加Integer元素,add2方法出现编译错误。
这里实际上耍的小把戏,跟上面的例子一样,List< ? >在这里做的事情是不能将任意元素(除了null)添加到List< ? >中,这就杜绝了小把戏的出现。
但是这样的编译错误让人无法接受,无法将任意元素添加到List< ? >中,那要他有何用,于是有限制的通配符在这里就派上了用场。
总结:这里List< ? >无限制通配符的作用仅仅是防止强制类型转换问题的发生,并没有实际的作用。
5.适合原生态类型的情况
1.规范中要求:在类文字中必须用原生态类型List
比如List.class
而不能List< String >.class
2.由于泛型类型在运行时是可以擦除的,所以在xx instanceof List
这样的语句中是没有问题的,变成xx instanceof List<?>
反而是多余的。