泛型

泛型

泛型也叫参数化类型 泛指某一类型,就是把“类型”当作参数传给类、接口或方法,是一种编译期的类型检查工具(让编译器帮你在编译期做类型==约束==,阻止不符合要求的类被传入),减少强转和运行时 ClassCastException。

  • 快速示例
List list = new ArrayList();
list.add("hello");
Integer x = (Integer) list.get(0); // 运行时炸:ClassCastException

List<String> list = new ArrayList<>();
list.add("hello");
Integer x = list.get(0); // 编译期直接报错,提示你应该修改代码

泛型类

  1. 示例
class Box<T> {
    private T value;  // 属性value的类型为T

    public void set(T v) {  // 参数v的类型是T
        value = v;
    }

    public T get() { // 方法get的返回值类型是T
        return value;
    }
}

Box<Integer> b = new Box<>();  //创建对象的时候自定义T的类型为Integer
b.set(123);
  1. ==泛型的声明==
    class Box<T, E> 可以指定多个类型。
    常用字母 E K T V,意为 Element Type Key Value。
    T, E 只能是引用类型,不能是基本数据类型。
    指定具体类型后可以传入该类型或其子类型。
    静态方法和静态属性中不能使用类的泛型,因为静态是和类相关的,在类加载的时候对象还没有创建 泛型不知道是什么类型。
    使用泛型的数组不可以初始化,因为数组的初始化需要指定长度,但你使用的是泛型 编译器并不知道泛型T的具体类型 只知道它是T类。
  2. 泛型类的写法
Box<String> stringBox = new Box<String>()(老写法)

Box<String> stringBox = new Box<>()(新写法,推荐)

Box stringBox = new Box()(如果什么都不写,等价于Object泛型)
Box<Object> stringBox = new Box<>()

这两种写法在功能和运行效果上没有任何区别,完全是一回事,唯一的区别在于Java 版本的历史演进和代码的简洁程度

泛型接口

interface Repository<T> {
    T findById(long id);
}

泛型接口的具体类型在 其它接口继承接口 类实现接口 的时候确定。
声明接口时:T 只是占位,没定。
某个子接口写了 extends Repository<\User>:在这里定为 User。
某个实现类写了 implements Repository<\User>:在这里定为 User。
如果继承/实现时仍然写 T:那就是“继续往下传”,直到某一层用具体类型替换它。

泛型方法

基本语法:
修饰符 <T, R…> 返回类型 方法名(参数列表){
}
public static <T> T first(List<T> list) {
    return list.get(0);
}
// 辨认技巧:方法返回值前面的 <T> 是“声明类型参数”,T是变量名。
  • 泛型方法 和 泛型类里面的方法
    这是两种不同的东西,后者只是使用了类的类型参数,前者是自己声明的类型参数。同名时遵循泛型方法里的定义。
    (A) 非泛型类里的泛型方法
class Utils {
    public static <T> T first(List<T> list) {
        return list.get(0);
    }
}

(B) 泛型类里也可以再写泛型方法(它有自己的类型参数)

class Car<T> {
    private T value;

    public <U, R> U convert(T f) { // U和R 是方法自己的
        
    }
}
//这里 T来自类 Box<T> U和R来自convert方法

通配符

Java 泛型里的通配符 ?表示“某个我现在不想/不能写死的类型”。它常用于方法参数,用来表达“我能接受一类泛型类型”,解决泛型“不变性”带来的不方便。
无界通配符<?>,支持任意类型的泛型
上界通配符<? extends A>,支持A类及A类的子类,规定了泛型的上限
上界通配符<? super A>,支持A类及A类的父类,规定了泛型的下限

Previous Article
Next Article

发表回复

Your email address will not be published. Required fields are marked *.

*
*

TOC