JAVA基础之泛型
包装类
在Java中,由于基本类型不是继承自Object,为了在泛型代码中可以支持基本类型,Java给每个基本类型都对应了一个包装类型
Byte、Short、Integer、Long、Float、Double、Character、Boolean
byte、short、int、long、float、double、char、boolean
装箱和拆箱
既然Java给每个基本类型提供引用类型,那就离不开装箱拆箱机制,引用类型可以
拆箱成基本类型,同样,基本类型也可以装箱成引用类型
- 隐式:由编译器自动帮我们完成装箱、拆箱操作
- 显式:通过代码手动完成拆箱、装箱操作
例如
Integer 和 int
Integer = 332
实际调用了Integer.valueOf(332)方法 // 自动装箱
同理 int = new Integer(32) //自动拆箱
调用了Integer.intvalue()方法
可以通过javap -c .class文件名
可以查看字节码文件内实际代码编译情况,class文件为java代码编译后文件
注意:频繁拆装箱会影响性能
什么是泛型
定义: 泛型:就是适用于许多许多类型。从代码上讲,就是对类型实现了参数
化。
使用
1.泛型类
在类后面加上<T>
,定义一个泛型类,例子如下:
//泛型类
public class MyArray <T>{
//泛型变量
public T member = null;
//泛型方法, ...可变参数
public T test(T... flied) {
return flied;
}
}
2.泛型方法
在方法上加<T>
//在方法上加
public static <T> T test(T filed) {
return filed;
}
泛型上界
语法
<T extends Class>
//表示泛型类型是Number或者Number子类
public class MyArray<T extends Number> {
//方法上界写法跟类一致
public static <T extends Number> T test(T filed) {
return filed;
}
}
泛型如何编译的
擦除机制
实际上,泛型只能在编译期存在,而运行期的时候JVM会自动将泛型擦除为Object类型
同样通javap -c 查看字节码文件
来查看运行机制
为什么不能实例化泛型类型数组
按照我们上述所说,泛型会被擦除为Object,那么如果泛型数据,应该被擦除为Object数组,但是却不通过编译
这是因为,泛型会导致存入数据不固定,可以是Integer也可以是String,这样就会导致数组不能整体转换,编译器认为是不安全的,所以报错,实际上数组也是一种类型
我们可以这么写,来解决报错
T[] array = (T[])new Object[];
或者通过反射
public T[] test(Class<T> tClass, int size){
return (T[]) Array.newInstance(tClass, size);
}
不过上述操作都不推荐,实际上我们通过看源码
采用的是Object,所以数据类型直接写成Object最好
泛型比较问题
泛型比较大小问题,如下图
发现编译报错,这是因为所有比较操作都是需要实现,Comparable<T>
接口·
如图,泛型并没有实现这个接口
解决:实现Comparable接口即可,泛型类或方法选一个实现就行,然后调用Comparable内部的compareTo() 方法
总结:
- 泛型是将数据类型参数化,进行传递
- 使用
<T>
表示当前类是一个泛型类。 - 泛型目前为止的优点:数据类型参数化,编译时自动进行类型检查和转换