由于系统中并不会真正生成泛型类,所以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
