由于系统中并不会真正生成泛型类,所以instanceof运算符后不能使用泛型类:
1 import java.util.Collection; 2 import java.util.ArrayList; 3 4 public class GeneicErrorInstanceof{ 5 public static void main(String[] args){ 6 Collection<String> cs = new ArrayList<>(); 7 if(cs instanceof ArrayList){ } 8 if(cs instanceof ArrayList<String>){ } 9 } 10 } View Code类型通配符:
当使用一个泛型类时(包括声明变量和创建对象两种情况),都应该为这个泛型类传入一个类型实参。若没有传入类型实际参数,编译器就会提出泛型警告。假设需要定义一
个方法,该方法里有一个集合形参,集合形参是不确定的 ,怎样定义?
1 import java.util.List; 2 import java.util.ArrayList; 3 4 public class GeneicTest{ 5 public void test(List c){ 6 for(int i = 0; i < c.size(); i++){ 7 System.out.println(c.get(i)); 8 } 9 } 10 11 public static void main(String[] args){ 12 List<String> list = new ArrayList<>(); 13 list.add("疯狂Java讲义"); 14 list.add("疯狂Android讲义"); 15 GeneicTest gt = new GeneicTest(); 16 gt.test(list); 17 } 18 } View Code更改上面代码,让List带上类型参数<Object>:
1 import java.util.List; 2 import java.util.ArrayList; 3 4 public class GeneicTest{ 5 public void test(List<Object> c){ 6 for(int i = 0; i < c.size(); i++){ 7 System.out.println(c.get(i)); 8 } 9 } 10 11 public static void main(String[] args){ 12 List<String> list = new ArrayList<>(); 13 list.add("疯狂Java讲义"); 14 list.add("疯狂Android讲义"); 15 GeneicTest gt = new GeneicTest(); 16 gt.test(list); 17 } 18 } View Code上面的编译错误,表明List<String>对象不能被当成List<Object>对象使用。
若Foo是Bar的一个子类型(子类或者子接口),而G是具有泛型声明的类或接口,G<Foo>并不是G<Bar>的子类型!这一点非常值得注意,因为它与大部分人的习惯认为是不
同的。
1 public class ArrayErr{ 2 public static void main(String[] args){ 3 //定义一个Integer数组 4 Integer[] ia = new Integer[5]; 5 //可以把一个Integer[]数组赋给Number[]变量 6 Number[] na = ia; 7 //下面代码编译正常,但运行时会引发ArrayStoreException异常 8 //因为0.5并不是Integer 9 na[0] = 1; 10 na[1] = 0.5; 11 } 12 } View Code数组允许将子类引用变量赋值给父类引用变量,但是父类引用变量存储的对象必须是子类对象,否则报错。
但是,Java在泛型设计时进行了改进,它不在允许吧List<Integer>引用变量赋值给List<Number>变量,这在根源上杜绝了类型不匹配的错误。
数组和泛型有所不同,假设Foo是Bar的一个子类型(子类或者子接口),那么Foo[] 依然是Bar[] 的子类型;但G<Foo>不是G<Bar>的子类型。
使用类型通配符:
为了表示各种泛型List的父类,可以使用类型通配符,类型通配符是一个问号(?),将一个问号作为类型实参传给List集合,写作:List<?>(意思是元素类型未知的List)
这个问号(?)被称为通配符,它的元素类型可以匹配任何类型。可以将上面的方法改为如下:
1 import java.util.List; 2 import java.util.ArrayList; 3 4 public class GeneicTest{ 5 public void test(List<?> c){ 6 for(int i = 0; i < c.size(); i++){ 7 System.out.println(c.get(i)); 8 } 9 } 10 11 public static void main(String[] args){ 12 List<String> list = new ArrayList<>(); 13 list.add("疯狂Java讲义"); 14 list.add("疯狂Android讲义"); 15 GeneicTest gt = new GeneicTest(); 16 gt.test(list); 17 } 18 } View Code