目录
泛型的引入
之前学习的数组里面是存放着整型或者自字符串中一种的数组,如果想要在一个数组里面放多种类型数据,我们该怎么去做呢?Object类或许是一个好的解决方法,因为Object类是所有类的父类,这样我们可以通过创建一个Object类的数组类解决这个问题。
java
class MyArray{
public Object[] array = new Object[10];
//创建一个Object类数组
public Object getPos(int pos){
return this.array[pos];
}
//返回对应位置的数据
public void setVal(int pos, Object val){
this.array[pos] = val;
}
//在对应的位置里存放数据
}
java
public static void main(String[] args) {
MyArray myArray = new MyArray();
myArray.setVal(0,10);
myArray.setVal(1,"hello");
//String ret = myArray.getPos(1);
//这里需要强转才能为ret赋值
String ret = String.valueOf(myArray.getPos(1));
System.out.println(ret);
}
虽然其中所有类型的数据都可以存放,但不难看出,这样的做法会出现以下不便的情况:
- 不同类型的数据需要强转才能输出
- 排序不够整齐,需要记录每个位置放着什么类型的数据
泛型
泛型
虽然当前所有类型的数据都可以存放到其中,但我们更却趋向于让数组内放一种类型的数据
所以,泛型的主要目的:就是指定当前的容器,要持有什么类型的对象。让编译器去做检查。此时,就需要把类型,作为参数传递。需要什么类型,就传入什么类型。
泛型的语法格式为:
class 泛型类名称<类型形参列表> {
// 这里可以使用类型参数
}
class 泛型类名称<类型形参列表> extends 继承类/* 这里可以使用类型参数 */ {
// 这里可以使用类型参数
}
在了解泛型的语法格式后,我们可以尝试把上面的Object类数组进行改写。
java
class MyArray<T>{
public Object[] array = new Object[10];
public T getPos(int pos){
return (T)this.array[pos];
}
public void setVal(int pos, T val){
this.array[pos] = val;
}
}
public class Test {
public static void main(String[] args) {
MyArray<Integer> myArray = new MyArray<>();
myArray.setVal(0,10);
myArray.setVal(1,19);
int ret = myArray.getPos(0);
System.out.println(ret);
//myArray.setVal(2,"not");
//不再成立,自动进行类型检查
}
//对于不同类型的数据,我们可以采用实例化不同的对象来实现
MyArray<String> myArray1 = new MyArray<>();
myArray1.setVal(2, "not");
String ret1 = myArray1.getPos(2);
System.out.println(ret1);
}
类名后的<T>代表占位符,表示当前类是一个泛型类。
这里我们可以发现,int ret *= myArray.getPos(0);*中不需要进行类型的强制转换,因为输出的一定是整型数据。
泛型类
泛型类的语法格式为:
泛型类<类型实参> 变量名; // 定义一个泛型类引用
new 泛型类<类型实参>(构造方法实参); // 实例化一个泛型类对象
java
MyArray<Integer> list = new MyArray<Integer>();
泛型只能接受类,所有的基本数据类型必须使用包装类。
如果编译器可以通过上下文推导出数据类型时,我们可以省略后面的类型书写:
java
MyArray<Integer> list = new MyArray<>();
泛型的上界
泛型的上界的语法格式为:
class 泛型类名称<类型形参 extends 类型边界> {
...
}
java
public class MyArray {
...
}
只接受 Number 的子类型作为 E 的类型实参