My Blog

Generics

Java 泛型

学习笔记,仅供参考

参考Oracle-javase-tutorial |


🧷 定义

泛型(Generic type) 即表示通用类型,可以指代多种类型。泛型也叫参数化类型,因为它将类型当作参数使用,就像函数的形参一样,只不过形参接收的是值,而它接收的是类型。比如,ClassName<T> 中的 T 就相当于形参,ClassName<String> 的 String 相当于实参。

早期时使用 Object 类来表示任意类型,但要强制类型转换才能完成赋值等操作,且当代码量或时间过长就会忘记要转换为啥类型,可能会引起异常,从而引入了泛型。它不用强制类型转换;若出现错误时,能在编译时就能找出和改正。

泛型类格式:public class ClassName<T1, T2, .. , Tn> , 代码块内部均可用 T 表示未知类型(接口也是如此)

泛型方法格式:public <T> T functionName (T t), 代码块、返回类型、参数类型均可使用 T 代表未知类型

其中,<T> 为泛型声明,表示该类或方法中使用了泛型

下面将泛型类与非泛型类做对比,以显示泛型得特点。

// Object 实现任意类型
public class Box {
    private Object obj;

    public Object getObj() {
        return obj;
    }
    public void setObj(Object obj) {
        this.obj = obj;
    }
}

// 使用
public class Test {
    public static void main(String[] args) {
        Box box = new Box();
        box.setObj("hello");
        String str = (String) box.getObj();  // 要提前得知存的类型是啥,再用强转赋值
        box.setObj(100);
        int num = (Integer) box.getObj(); 
    }
}

/*  【总结】
    从上可知,要想赋值得提前知道是啥类型,再强转;当类型多次变换时
    就会带来困难,无法得知是何类型,从而强制错误,引起异常
*/

/******************************************/

// 泛型类
public class Box<T> {
    private T t;

    public T get() {
        return this.t;
    }
    public void set(T t) {
        this.t = t;
    }
}

// 使用
public class Test {
    public static void main(String[] args) {
        Box box<String> = new Box<>();  // 泛型类在声明时,就将类型确定下来
        box.set("hello");
        String str = box.get();  // 赋值不需强转,因为类型已经明确
        box.set(100);  // IDEA 报错,编译时错误,利于修改   
    }
}