Java 泛型

泛型

泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型)。也就是说在泛型使用过程中,操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法

引入泛型的意义在于:

适用于多种数据类型执行相同的代码(代码复用)

(泛型这个东西理论有点抽象 还是实际的代码例子来理解会易懂一点)

泛型类

首先我们常见的常规类:

public class Box {
    private String str;
    public String getStr() {
        return str;
    }
    public void setStr(String str) {
        this.str = str;
    }
}

然后我们改造成泛型类:类前面加上< T > :

public class Boxs<T>{
    private T data;

    private String code;

    private String traceId;

    public Boxs() {}

    private Boxs(T data, String code, String traceId) {
        this.data = data;
        this.code = code;
        this.traceId = traceId;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getTraceId() {
        return traceId;
    }

    public void setTraceId(String traceId) {
        this.traceId = traceId;
    }

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

    public T getData() {
        return data;
    }
}

这里的T代表泛型参数 起什么都可以 只不过一般规范喜欢叫T。

这里理解上要注意

  • 泛型类 意味着 这个类里面存在 泛型类型 类名后面加一个< T > 就是一个声明 告诉调用者 里面有泛型 。
    但是不代表只能有泛型类型参数,可以有常规类型。 比如上面就加了几个常规类型进去。
  • 泛型参数可以有多个 比如 ,常见的 key-value 泛型类

定义了刚才这个泛型类之后 我们在test main函数中 实例一下,这里就体现出泛型的强大了 我们可以随意界定任何类型 来确定泛型中的这个T, 比如 integer,string, 而且除了泛型参数T 类中其他的常规参数 也可以正常使用 和正常类没区别:

        /**
         * 定义了一个Boxs泛型类对象
         * */
        Boxs<Integer>boxOfInt = new Boxs<>();
        boxOfInt.setData(1);
        System.out.println(boxOfInt.getData());

        Boxs<String>boxOfStr = new Boxs<>();
        boxOfStr.setData("apple");
        boxOfStr.setCode("007");
        System.out.println(boxOfStr.getData());

这里你可以用任意类型来替换 T ,但是你会发现,定义泛型类的时候 T是任意类型 但是你实例化这个Boxs类的时候 这里的T需要明确类型。

泛型方法

了解了泛型类之后,自然就引出了泛型方法——也就是方法的返回值是泛型, 可以看到上面的泛型类代码中已经有一个简单的泛型方法:

    public T getData() {
        return data;
    }

这里返回值是泛型T 也就是 set进去的T是什么类型 你调用get方法的时候取出来的T就是什么类型

看一下 一个标准的泛型方法:
Java 泛型_第1张图片
新手注意:

  • 和泛型类一样 最前面 要有一个声明 < T >,它是一个声明 相对于告诉调用者 “注意这里涉及到泛型哦”
  • 后面第二个T才是 真正的方法类型,和常规的java方法一样, 方法类型是什么 就返回什么 方法类型是T 就返回T

比如在刚才的Boxs< T > 泛型类中我们 加一个静态的泛型方法 用来得到一个Boxs< T >类实例:

    private Boxs(T data, String code, String traceId) {
        this.data = data;
        this.code = code;
        this.traceId = traceId;
    }

    public static <T> Boxs<T>create(T data, String code, String traceId) {
        return new Boxs<>(data, code, traceId);
    }

这里对比之前的get方法 这是把方法类型从T 换成了类< T > ,

最后说一个泛型类和泛型方法 最最常见的应用场景,应该大多数java程序员都见过: 就是web开发中 统一返回前端数据类

web应用中 要统一一个 返回前端的数据结构,就会用的泛型

比如

public class Result<T> implements Serializable{
  int code //http状态码
  boolean success //请求是否成功
  T data //业务数据
}

泛型参数限制

什么叫参数限制呢 之前T是什么类型都可以 ,但是你不想T的类型完全无限制,这种情况 可以用java的继承思想 来用父类限定子类
写法是 < T extends Father>

来个例子, 比如我们知道 java中有一个 Number 类型,它是八种数据类型包装类对象的父类:

IntegerDoubleFloatShortLongBooleanByteCharacter

给刚才的Boxs 加上 限制:

public class Boxs<T extends Number>{ ...........}

Java 泛型_第2张图片
这种情况下就会发现 String类型就会报错 因为它不是Number的子类,Integer类型就没问题

你可能感兴趣的:(Java笔记,java)