泛型
学生成绩可能是数字类型,也可能是字符串类型,如何存放可能出现的两种类型呢:
public class Score {
String name;
String id;
Object value; //因为Object是所有类型的父类,因此既可以存放Integer也能存放String
public Score(String name,String id,Object value){
this.name=name;
this.id=id;
this.value=value;
}
}
以上方法虽然解决了多种类型存储的问题,但是Object类型在编译阶段并不具有良好的类型判断能力,很容易出现:
public static void main(String[] args) {
Score score=new Score("数学","aa","优秀"); //是String类型的
Integer number=(Integer) score.getValue();
//获取成绩需要进行强制类型转换,虽然并不是一开始的类型,但是编译不会报错
}
由于是Object类型,所以并不能直接判断存储的到底是String还是Integer,取值只能进行强制类型转换,显然无法在编译期确定类型是否安全,项目中代码量非常大,进行类型比较又会导致额外的开销和增加代码量,如果不比较又容易出现类型转换异常,代码的健壮性有所欠缺。
为了解决以上问题,JDK5新增了泛型,它能够在编译阶段检查类型安全,大大提升开发效率。
泛型类
定义泛型类:
public class Score<T> { //泛型类需要使用<>,在里面添加1-N个类型变量
String name;
String id;
T value; //T会根据使用时提供的类型自动变成对应类型
public Score(String name,String id,T value){ //这里的T可以是任何类型,但是一旦确定就不能修改了
this.name=name;
this.id=id;
this.value=value;
}
}
public static void main(String[] args) {
Score<String> score=new Score<>("数学","aa","优秀");
//使用时跟上<>并在其中填写明确要使用的类型
}
泛型将数据类型控制在了编译阶段, 在编写代码时就能明确泛型的类型,类型不符合将无法编译通过。
1、因为是具体使用对象时才会明确具体类型,所以说静态方法中不能用。
2、方法中使用待确定类型的变量时,因为不明确类型则会默认这个变量是一个Object类型的变量(即不能使用String等类型中的方法)。可对其进行强制类型转换但没必要。
3、不能通过这个不确定的类型变量直接创建对象和对应的数组。
4、具体类型不同的泛型类变量,不能使用不同的变量进行接收。
5、如果要让某个变量支持引用确定了任意类型的泛型,可以使用?通配符。
public static void main(String[] args) {
Score<String> score=new Score<>("数学","aa","优秀");
Score<?>score1=score;
}
如果使用通配符,由于类型不确定,所以说具体类型同样会变成Object。
6、泛型变量可以定义多个,多个类型变量用,隔开。在使用时需要将这三种类型都进行明确指令。
7、泛型只能确定为一个引用类型,不支持基本类型。
要存放基本数据类型的值,我们只能使用对应的包装类。
如果是基本类型的数组,因为数组本身是引用类型,所以是可以的。