泛型
学生成绩可能是数字类型,也可能是字符串类型,如何存放可能出现的两种类型呢:
public class Score {String name;String id;Object value; //因为Object是所有类型的父类,因此既可以存放Integer也能存放Stringpublic 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、泛型只能确定为一个引用类型,不支持基本类型。
要存放基本数据类型的值,我们只能使用对应的包装类。
如果是基本类型的数组,因为数组本身是引用类型,所以是可以的。