开发喵星球

泛型

pPeHp90.png pPeHkB4.png

本文内容是泛型的梳理和总结,本文内容包括:

泛型

什么是泛型:泛型是指数据类型可变

Java 泛型(Generics) 是 JDK 5 中引入的一个新特性。使用泛型参数,可以增强代码的可读性以及稳定性。

编译器可以对泛型参数进行检测,并且通过泛型参数可以指定传入的对象类型。

不使用泛型,数据类型被固定了

public class StudentManager {
    String field;
    public String get() {
        return this.field;
    }
}

分析:

  1. StudentManager类的属性 field 类型是固定的
  2. StudentManager类的方法 get 的返回值时固定的

如果在开发中数据的类型要求是可以变化的,例如field的类型可能是String,也可能是Integer,怎么实现?

使用泛型可以实现吗,==泛型就是让类型可变==

泛型分类

泛型有三类

泛型接口

接口中方法的返回值类型由子类确定。

//子类实现泛型接口时,必须指定T的具体类型
public interface IStudent<T> {
    public T get();
}
public class Graduate implements IStudent<Graduate>{

    @Override
    public Graduate get() {
        return new Graduate();
    }
}
public class UnderGraduate implements IStudent<UnderGraduate> {

    @Override
    public UnderGraduate get() {
        return new UnderGraduate();
    }
}

泛型通常使用一个大写字母表示,例如T,E

泛型的实际类型是子类或者调用时,由子类或调用者传入实际类型。

下图是泛型接口中类型传入流程示意图

image-20230912160527380

泛型类

类中属性类型、方法参数类型、方法返回值类型由调用者确定。

//在实例化泛型类时,必须指定T的具体类型
public abstract class Worker<E> {
    public abstract E get(E e);
}
public class Driver extends Worker<String> {
    @Override
    public String get(String e) {
        return null;
    }
}
public class Doctor extends Worker<Integer>{
    @Override
    public Integer get(Integer e) {
        return null;
    }
}

下图是泛型类中类型传入流程示意图

image-20230912161152329

泛型方法

public class Person {
    public <E,T> T get(E e) {//<E,T>是泛型方法的特征,写在方法返回值前面
        return null;
    }
    
    public <T> void set(T e) {//<T>是泛型方法的特征,写在方法返回值前面
        
    }
    
    public static void main(String[] args) {
        Person p =new Person();
        // 在.和方法名之间传入泛型的类型
        Integer i = p.<String,Integer>get("abc");
        Double d = p.<Object,Double>get("abc");
        
        //<String>是调用泛型方法时传入泛型的具体类型
        p.<String>set("abc");
        
        //调用泛型方法时,如果不传入泛型的具体类型,泛型方法也能根据传入参数的类型推断出泛型的类型为String
        //本例中,通过方法参数"abc"推断出T为String类型,推荐这种调用方式
        p.set("abc");
    }
}

下图是泛型方法中类型传入流程示意图

image-20230912161647860

当泛型遇到重载

public class GenericTypes {

    public static void method(List<String> list) {
        System.out.println("invoke method(List<String> list)");
    }

    public static void method(List<Integer> list) {
        System.out.println("invoke method(List<Integer> list)");
    }
}

上面这段代码,有两个重载的函数,因为他们的参数类型不同,一个是List<String>另一个是List<Integer> ,但是,这段代码是编译通不过的。因为参数List<Integer>List<String>编译之后都被擦除了,变成了一样的原生类型 List,擦除动作导致这两个方法的特征签名变得一模一样。

泛型的使用场景

集合是泛型使用最常见的场景,例如

List<Integer> list = new ArrayList();
   
分类:Java/OOP 作者:开发喵 发表于:2023-09-12 16:26:05 阅读量:120
<<   >>


powered by kaifamiao