最近开始写代码的时候越来越觉得基础很重要,不同的设计思路和写的方法对代码执行效率会有很大影响。于是翻了翻书,做个简单的整理。
关于java泛型,有了些新的理解。
1、泛型是什么?
在jdk1.5之前,java容器是没有办法记住它里面存储的对象的类型的,会把所有的对象当成object类型来处理,于是当从集合中取出对象的时候,需要做强制类型转换,这种转换一方面会让代码显得很臃肿;另一方面也很容易带来ClassCastException。
所以在jdk1.5种引入了泛型,可以规定集合中对象的类型。所谓泛型,就是指参数化类型,将类型定义成一个参数的形式,也可以称之为类型形参。
在引入了泛型之后,一方面使得代码更简洁,另一方面也提供了编译期的类型安全检查,使得代码更健壮。
2、泛型是怎么工作的?
泛型的过程是通过类型擦除来实现的。java的泛型是伪泛型,编译器在编译时擦除了所有类型相关的信息,在运行时不存在任何类型相关的信息,保证和java 5 之前的版本类库的兼容性,这个过程称之为类型擦除。但是在传入时,则必须保证参数类型和指定的类型一致,在编译之前编译期会做检查,java的泛型都是在编译期这个层次实现的。
3、数组中可不可以用泛型?
容器和数组是有区别的。数组中可以存放值或者对象,但是容器中只能存放对象(其实是存放的对象的引用,简称为对象)。另外,还必须要有概念,数组是不支持泛型的,所以相应的,数组中保存的对象是不能提供编译期类型安全检查的。
4、List、List<Object>以及List<?>的区别?
List<?> 是一个未知类型的List
List<Object> 是任意类型的List
List 是一个原始类型的List,在编译时编译器不会对它里面的对象做类型安全检查。
还有一点需要注意,任意一个List<Object> 都可以赋值给List类型的变量。但是对于一个指定类型的容器,比如说List<String> 就不能赋值给List<Object>类型的变量。为什么会这样?举个例子,List<Object>中可以存储String,但是也可以存放Integer类型的变量。但是List<String>中只能存储String。
5、关于限定通配符和非限定通配符的理解
<?> 非限定通配符,表示某一种未知类型的泛型
<? extends T> 限定通配符,表示类型参数必须继承于T,也就是说,必须是T的子类,此时也就设定了通配符的上限
<? super T> 限定通配符, 表示类型参数必须是T的父类,此时则设定了通配符的下限