Java基础-泛型

116 阅读2分钟

泛型类、泛型接口和泛型方法

泛型类

/**
 * 泛型类
 * 创建对象时指定类型
 */
public class NormalGeneric<T> {
    private T data;

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public static void main(String[] args) {
        NormalGeneric<String> normalGeneric = new NormalGeneric<>();
        normalGeneric.setData("OK");
        String result = normalGeneric.getData();
    }
}

泛型接口

/**
 * 泛型接口
 */
public interface IGeneric<T> {
    public T next();
}

/**
 * 不指定具体类型
 */
public class IGenericImpl<T> implements IGeneric<T>{
    @Override
    public T next() {
        return null;
    }
}

/**
 * 指定具体类型
 */
public class IGenericSpecificTypeImpl implements IGeneric<String>{
    @Override
    public String next() {
        return null;
    }
}

泛型方法

/**
 * 泛型方法,该方法如果在泛型类中,如果类指定的泛型也是 T,他们互不影响
 * 使用方法时指定类型
 */
public <T> T genericMethod(T a){
    return a;
}

如何限定类型变量

/**
 * 限定 T 必须实现 Comparable
 * 使用 & 符号可以指定多个限定类型
 * 类和接口混用,类必须在第一个且只能有一个,接口可以有多个
 */
public <T extends Comparable> T min(T a,T b){
    return a.compareTo(b) > 0? b:a;
}

泛型使用中的约束和局限性

不能实例化类型变量

静态域或静态方法不能应用类型变量

不允许使用 instanceof

不能捕获泛型类型对象

泛型类型继承规则

public class Carbon {
}

public class Person extends Carbon{
}

public class Man extends Person{
}

public class Pair<T> {
}

Pair<Person> 和 Pair<Man> 没有任何继承关系
Pair<Person> person = new Pair<>();
Pair<Man> man = new Pair<>();

泛型中通配符类型

?为通配符,出现在方法行参数,解决调用 print 不能传入 Pair<Man> 类型问题
public static void print(Pair<? extends Person> p){
    
}

可以传入 Pair<Person>Pair<Carbon>,不能传入 Pair<Man>
public static void print(Pair<? super Person> p){
    
}

set 和 get 方法中的使用

extends 用于安全的访问数据

super 用于安全的写入数据,可以安全的写入 Person 和 Person 的子类

虚拟机是如何实现泛型的

泛型擦除

擦除前

public class NormalGeneric<T> {
    private T data;

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }
}

擦除后

public class NormalGeneric<Object> {
    private Object data;

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }
}

T extends Comparable&Serializable 擦除后的类型是 Comparable,在使用 Serializable 的方法时会强转成Serializable

泛型的原始类型记录在 Signature 中