【 java基础】泛型详解

什么是泛型

Java中的泛型(Generics)是一种对数据类型进行抽象的机制,它允许在编译时指定未知的数据类型,以提高代码的灵活性和重用性。泛型可以应用在类、接口、方法等各种场景中,可以用于定义参数类型、返回值类型、集合类型等等。我们可以在编译时检查类型安全性,避免运行时类型转换错误。

泛型的使用

泛型有三种使用方式,分别为:泛型类、泛型接口、泛型方法

泛型类
  1. 基本语法
//此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型
public class MyClass<T> {
  private T value;
  public void setValue(T value) {
    this.value = value;
  }
  public T getValue() {
    return value;
  }
}

在这个例子中, 表示类型参数,可以用任何标识符代替。这个类中的 value 属性和 setValue 和 getValue 方法都使用了泛型类型 T,这意味着它们可以接受或返回任何类型的值。

通过使用泛型,我们可以让这个类具有更高的灵活性,可以在不同的场景中使用,例如:

MyClass<String> stringObj = new MyClass<>();
stringObj.setValue("Hello, world!");
String str = stringObj.getValue();
System.out.println(str); // 输出 "Hello, world!"

MyClass<Integer> intObj = new MyClass<>();
intObj.setValue(42);
int num = intObj.getValue();
System.out.println(num); // 输出 42

在这个例子中,我们创建了两个 MyClass 的实例,分别使用了不同的类型参数 String 和 Integer。这样,我们可以避免在每个场景中都创建不同的类来处理不同的数据类型,而是使用一个通用的类来处理不同的数据类型。

泛型接口
  1. 基本语法
public interface MyInterface<T> {
    public T getValue();
    public void setValue(T value);
} 

在这个例子中,我们定义了一个泛型接口 MyInterface,它有一个泛型类型参数 T,用于定义 getValue 和 setValue 方法的参数类型和返回值类型。

public class MyClass implements MyInterface<String> {
    private String value;
    public void setValue(String value) {
        this.value = value;
    }
    public String getValue() {
        return value;
    }
} 

在这个例子中,我们定义了一个实现 MyInterface 接口的类 MyClass,并指定泛型类型参数为 String。这样,我们就可以在 MyClass 中使用泛型类型参数 T,并在编译时指定其具体类型为 String。

泛型方法

泛型类,是在实例化类的时候指明泛型的具体类型;泛型方法,是在调用方法的时候指明泛型的具体类型 。

public class MyUtils {
/*
 * 说明:
 *     1)public 与 返回值中间<T>非常重要,可以理解为声明此方法为泛型方法。
 *     2)只有声明了<T>的方法才是泛型方法,泛型类中的使用了泛型的成员方法并不是泛型方法。
 *     3)<T>表明该方法将使用泛型类型T,此时才可以在方法中使用泛型类型T。
 *     4)与泛型类的定义一样,此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型。
 */
    public <T> T getFirstElement(List<T> list) {
        if (list == null || list.size() == 0) {
            return null;
        }
        return list.get(0);
    }
}

在这个例子中,我们定义了一个泛型方法 getFirstElement,它有一个泛型类型参数 T,用于定义 list 参数的类型和返回值类型。在方法体中,我们检查 list 是否为空或者长度为 0,如果是,则返回 null,否则返回 list 的第一个元素。

泛型通配符

通配符用于表示一个未知类型的参数,可以使用 ? 表示。通配符可以用在泛型方法、泛型类和通配符类型参数中。

// 这个方法接受一个未知类型的 List,然后打印出其中的所有元素。
public static void printList(List<?> list) {
    for (Object elem : list)
        System.out.print(elem + " ");
} 
泛型边界

边界可以限制泛型类型参数的范围,可以使用 extends 或 super 关键字来表示。extends 用于限制泛型类型参数必须是某个类的子类,而 super 用于限制泛型类型参数必须是某个类的父类。

  1. 泛型添加上边界(<? extends T>)
public static void printList(List<? extends Number> list) {
    for (Object elem : list){
        System.out.print(elem + " ");
    }
} 

List<String> stringList = new ArrayList<>();
List<Integer> integerList = new ArrayList<>();
List<Double> doubleList = new ArrayList<>();

// 这一行代码编译器会提示错误,因为String类型并不是Number类型的子类
printList(stringList);

printList(integerList);
printList(doubleList);
  1. 泛型添加下边界(<? super T>)
 public class MyUtils {
    public static <T> void copy(List<? super T> dest, List<T> src) {
        for (T element : src) {
            dest.add(element);
        }
    }
}

List<Number> dest = new ArrayList<>();
List<Integer> src = new ArrayList<>();
src.add(1);
src.add(2);
MyUtils.copy(dest, src);

在这个例子中,我们定义了一个泛型方法 copy,它有两个参数:一个下边界为 <? super T> 的 dest 参数和一个泛型类型为 T 的 src 参数。在方法体中,我们遍历 src 列表中的所有元素,并添加到 dest 列表中。

泛型类型擦除

Java泛型中的类型擦除是指在编译时将泛型类型参数擦除为它们的上界或 Object 类型,并在运行时使用 Object 类型来处理泛型类型参数。这是因为 Java 泛型是在编译时进行类型检查的,而在运行时泛型类型参数的具体类型已经被擦除了。

public class MyList<T> {
    private List<T> list = new ArrayList<>();
    public void add(T element) {
        list.add(element);
    }
    public T get(int index) {
        return list.get(index);
    }
}

当我们编译这个类时,Java 编译器会将所有的泛型类型参数擦除为它们的上界或 Object 类型。例如,在这个例子中,泛型类型参数 T 的上界为 Object,因此编译器会将所有的 T 类型擦除为 Object 类型。这就意味着,当我们在运行时调用 MyList 类中的方法时,所有的泛型类型参数 T 都已经被擦除了,而使用的是 Object 类型来处理它们。

总结
  • java中泛型的知识体系分为几个部分:泛型类、泛型方法、泛型接口、通配符、泛型上下边界、类型擦除。
  • 泛型的好处:可以在编译时进行类型检查,并避免运行时类型转换错误。同时,我们还可以使用通配符和边界来限制泛型类型参数的范围,使代码更加健壮和可维护。
    在这里插入图片描述
    在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值