# 泛型 Uncompleted
如果一个方法接收List<Object>
作为形式参数,那么如果尝试将List<String>
的对象作为实际参数传进去,就会发现无法通过编译。尽管String
是Object
的子类,但是实际上会产生隐含的类型转换问题,所以编译器是禁止这样的行为的。
# 类型擦除
在生成的Java字节代码中是不包含泛型中的类型信息的。使用泛型的时候加上的类型参数会被编译器在编译的时候去掉,这个过程就叫做类型擦除。比如,List<String>
和List<Object>
等类型在编译之后都会变成List
。JVM看到的只有List
,而由泛型附加的类型信息对于JVM来说是不可见的。
# 通配符
在使用泛型类的时候,既可以指定一个具体的类型,如List<String>
就声明了具体类型是String
类型;但也可以通过通配符?
来表示未知类型,如List<?>
就表示了List
中包含的元素类型是未知的,也就意味着所有类型都是可以的。
但注意List<?>
并不等同于List<Object>
。因为List<Object>
确定了List
中包含的是Object
及其子类,在使用的时候都可以通过Object
来进行引用,而List<?>
其中包含的元素是不确定的。如果其包含的是String
类型的,那往里添加Integer
类型的元素就是错误的。
在某些情况下,可以使用上下界来限制未知类型的范围。如通过List<? extends Number>
来说明List
中可能包含的元素类型是Number
及其子类。而List<? super Number>
则说明List
中包含的是Number
及其父类。当引入了上界之后,在使用类型的时候就可以使用上界类中定义的方法。