目录
包装类
一、什么是包装类?
包装类就是基本数据类型所对应的引用类型,其能提供更多的功能,且由于泛型的参数只能使用类因此java提供了包装类。
二、基本数据类型和其对应的包装类
基本数据类型 | 包装类 |
byte | Byte |
short | Short |
int | Integer |
long | Long |
char | Character |
float | Float |
double | Double |
boolean | Boolean |
三、装箱和拆箱
-
装箱:将一个基本数据类型的值放入包装类类型对象的某个属性中
//装箱,新建一个Integer类型的对象,将int类型的值放入
int i = 12;
Integer ii = Integer.valueOf(i);
//自动装箱,为了方便java提供了自动装箱机制
int j = 12;
Integer jj = j;
- 拆箱:将包装类对象中的值取出,放入到基本数据类型变量中
//拆箱:将Integer类型对象中的值放到int类型变量中
Integer ii = new Integer(12);
int i = ii.intValue();
//自动拆箱:为了方便java同样提供了自动拆箱机制
Integer jj = new Integer(12);
int j = jj;
泛型
一、什么是泛型?
在一般的类或方法中只能使用具体的类型,为了解决这个问题,JDK.8中引入新的语法——泛型,泛型语法使得类和方法可以适用于多种类型,实现了类型的参数化。
二、泛型类
-
泛型类的创建格式
class 泛型类名称 <类型参数列表>{
//类中代码(可以使用类型参数)
}
-
泛型类的使用格式
泛型类名称<类型实参> 变量名 = new 泛型类名称<类型实参>(构造方法实参);
//后面<>中参数可省略不写
-
举例
创建泛型类
//创建泛型类
class Test<T>{
//创建数组
private Object[] t = new Object[10];
//构建方法
public void set(T t, int sub){
this.t[sub] = t;
}
public T get(int sub){
return (T)this.t[sub];
}
}
实例化泛型类并使用其中方法
//实例化泛型类并使用其中方法
public class demo {
public static void main(String[] args) {
//类型参数为Integer
Test<Integer> test1 = new Test<>();
test1.set(2,0);
test1.set(2,1);
test1.set(2,2);
test1.set(2,3);
Integer j = test1.get(2);
//类型参数为String
Test<String> test2 = new Test<>();
test2.set("hello",0);
test2.set("hi",1);
test2.set("你好",2);
test2.set("world",3);
String str = test2.get(1);
}
}
-
注意
- 泛型参数只能是类,不能是基本数据类型
- 泛型类型不能实例化(即不能new T() 或 直接创建泛型数组【可通过反射创建 】)
三、泛型方法
-
泛型方法的创建
方法限定符<类型形参列表> 返回值类型 方法名(形参列表) {
//方法内部
}
-
泛型方法的使用
类名.<类型形参列表>方法名(参数列表);
//<>可省略,其能根据参数列表自动推导
-
实例
泛型方法的创建
class Test{
//完成数组内容的交换
public static<T> void swap(T sd, T[] tArr, int i, int j){
T t = tArr[i];
tArr[i] = tArr[j];
tArr[j] = t;
}
}
泛型方法的使用:
public class demo {
public static void main(String[] args) {
//当类型参数为Integer时
Integer[] arr = {1,2,3,4,5,6};
Test.swap("asfd",arr, 0 , 2);
//当类型参数为String时
String[] strArr = {"hello", "hi", "你好", "world"};
Test.swap(1,strArr, 0, 2);
}
}
-
注意
- 使用泛型方法时<>可省略,其能通过后面的参数列表自动推导
- 当没加<>且参数列表中无法推导出时,默认为Object类型
四、泛型的上界
在定义泛型类或者泛型方法时,可对传入的类型参数做一些限制,可以使用类型边界来约束。
-
使用方式
//在泛型方法或泛型类的创建中
<类型形参 extends 类型边界>
-
实例
一、规定所传入类需实现某个接口
//规定所传入的类必须实现了Comparable接口
class Test<T extends Comparable<T>>{
public int tCom(T t1, T t2){
//使用已实现的Comparable接口中的方法
return t1.compareTo(t2);
}
}
二、规定所传入类需继承某个类
class Animal{
private int age;
private String color;
}
//规定所传入的类必须继承于Animal类,或是继承于Animal的子类
//也可直接传入Animal类
class Test<T extends Animal>{
}
五、泛型的编译机制
-
擦除机制
在编译过程当中,会将所有的T替换为Object,java的泛型机制是在编译级别实现的,编译形成的字节码不包含泛型的类型信息和类型边界信息(实质上java的泛型机制可以理解为一种类型安全检查机制)
-
为什么不能实例化泛型类型?
因为在编译过程中T会替换为Object类型,而new Object () 并无实际意义,因此不能实例化
-
为什么不能直接实例化泛型数组?
因为数组的特殊性,其必须知道所持有的确切类型,以保证类型安全,而泛型擦除机制会移除参数类型信息,因此不能直接实例化泛型数组