术语介绍:声明中具有一个或者多个类型参数的类或者接口,就是泛型类或者接口。
例如:List接口就有单个参数类型E,表示列表的元素类型。
每个泛型都定义了一个原生态类型。
例如:List<E>相对应的原生态类型是List。
如果有设置泛型,则插入错误的类型,在编译的时候就会出错。如果没有,则只有当在运行的时候(取出强转)出错。
如果要使用泛型,但不确定或者不关心实际的类型参数,就可以使用一个问号代替。
例如:泛型Set<E>的无限制通配符类型为Set<?>(读作“某个类型的集合”)
问:原生态List和参数化的类型List<Object>之间到底有什么区别呢?
答:不严格的说前者逃避了泛型检查,后者则明确告知编译器,它能够持有任意类型的对象。虽然你可以将List<String>传递给类型List的参数,但是不能将它传给类型List<Object>的参数。泛型有子类型化的规则,List<String>是原生态类型的一个子类型,而不是参数化类型List<Object>的子类型。
这个规则有两个小小的例外。
- 在类文字中必须使用原生态类型。规范不允许使用参数化类型(但是允许数组类型和基本类型)
例如:List.class,String[].class和int.class。 - 由于泛型信息可以在运行时被擦除,因此在此参数化类型而非无限制通配符类型上使用instanceof操作符是非法的。用无限制通配符类型代替原生态类型,对instanceof操作符的行为不会产生任何影响。