泛型 (常用的泛型标识:T、E、K、V)
<? extends Person> 泛型上限 类型为Person 或Person的子类
<? super student> 泛型下限 类型为student 或student的父类
泛型上限:可以在定义泛型类和方法参数上使用
泛型下限:主要在方法参数上使用
泛型类:(是在实例化类的时候指明泛型的具体类型)
1、泛型的类型参数只能是引用类型,值类型需要使用对应的包装类类型
2、泛型类,如果没有指定具体的数据类型,此时操作类型是Object
3、泛型类型在逻辑上可以看成是多个不同的类型,但实际上都是相同类型
4、泛型类的成员方法,不能定义为 static
public class A<T>{
private T key;
public A(T key){
this.key = key;
}
public T getKey(){
return key;
}
public void setKey(T key){
this.key = key;
}
// 泛型类的成员方法,不能定义为 static
// public static T methodA(){
// }
}
泛型方法:(是在调用方法的时候指明泛型的具体类型)
Integer[] arr = {1, 8, 15, 6, 3};
Double[] douArr = {10.5, 25.1, 4.9, 1.8};
String[] strArr = {"我","是","字","符","串"};
methodB(strArr); // 如果不是泛型,就要对这三种类型的数据分别重载methodB的方法
public <E> E methodA(ArrayList<E> list){
return list.get(random.nextInt(list.size));
}
public <E> E methodB(E[] arr){
return arr[2];
}
public <E> E methodC(E e){
return e;
}
public static <E> void methodB(E[] arr){
for(int i=0;i<arr.length; i++){
System.out.println(arr[i]);
}
}
继承:
子类也是泛型类,子类和父类的泛型类型要一致
class ChildGeneric extends Generic
子类不是泛型类,父类要明确泛型的数据类型
class ChildGeneric extends Generic
泛型接口:
1、实现类不是泛型类,接口要明确数据类型
class B implements A{}
2、实现类也是泛型类,实现类和接口的泛型类型要一致
class B implements A{}
interface 接口名 <泛型标识1,泛型标识2,...>{
泛型标识 方法名();
...
}
类型擦除
//无限制类型擦除
public class Erasure<T>{
public T key;
public T getKey(){
return key;
}
public void setKey(T key){
this.key = key;
}
}
=>
public class Erasure {
public Object key;
public Object getKey(){
return key;
}
public void setKey(Object key){
this.key = key;
}
}
//有限制类型擦除
public class Erasure<T extends Number>{
public T key;
public T getKey(){
return key;
}
public void setKey(T key){
this.key = key;
}
}
=>
public class Erasure {
public Number key;
public Number getKey(){
return key;
}
public void setKey(Number key){
this.key = key;
}
}
擦除方法中类型定义的参数
//擦除方法中类型定义的参数
public <T extends Number> T getValue(T value){
return value;
}
=>
public Number getValue(Number value){
return value;
}
//桥接方法
public interface Info<T>{
T info(T var);
}
public class InfoImpl implements Info<Integer>{
@Override
public Integer info(Integer var){
return var;
}
}
=>
public interface Info{
Object info(Object var);
}
public class InfoImpl implements Info{
public Integer info(Integer var){
return var;
}
// 桥接方法,保持接口和类的实现关系
@Override
public Object info(Object var){
return info((Integer) var);
}
}
泛型数组的创建
可以声明带泛型的数组引用,但是不能直接创建带泛型的数组对象
//不能直接创建带泛型的数组对象
ArrayList<String>[] listArr = new ArrayList<String>[5]
ArrayList<String>[] listArr = new ArrayList[5];
ArrayList<Integer>[] listArr = new ArrayList<>();
//弊端例子:
ArrayList[] list = new ArrayList[5];
ArrayList<String>[] listArr = list;
ArrayList<Integer>intList = new ArrayList<>();
intList.add(100);
list[0] = intList; //整数数组付给了String泛型数组
//就会出现数据类型转换异常“java.lang.ClassCastException”
//可以通过java.lang.reflect.Array的newInstance(Class<T>,int) 创建T[]数组
实例:抽奖活动
1、抽奖品
2、抽现金