📜  讨论Java泛型(1)

📅  最后修改于: 2023-12-03 14:57:36.520000             🧑  作者: Mango

Java 泛型介绍

什么是 Java 泛型?

Java 泛型是 Java 5 中引入的一个新特性,它为 Java 语言引入了参数化类型的概念,以便作为一个通用的类型来处理数据。

早期的 Java 版本只支持指定参数类型的方法,例如 String 类型的 List。这种方法非常局限性,如果要处理其他类型,那么需要为每个类型写一个新的方法。

泛型的好处

使用 Java 泛型的好处在于可以创建适用于多种类型的代码。不仅减少了代码的冗余,还能保证类型安全和提高代码可读性。

除此之外,泛型还能在编译时检查类型错误,并提供更好的异常处理,让开发更加优雅和高效。

泛型的基本用法

Java 泛型可以定义类、接口和方法,下面是这三种方法的定义方式:

泛型类

在类名后加上 <T>,T 就是泛型类型,意思是这个类可以接受任何类型参数。

public class Box<T> {
  private T t;
  public void set(T t) { this.t = t; }
  public T get() { return t; }
}
泛型接口

泛型接口和泛型类一样,只需将接口名后的 <T> 换成自己需要的泛型标识符即可。

public interface Pair<T, V> {
  public T getKey();
  public V getValue();
}
泛型方法

泛型方法可以在方法上加上泛型声明,并使用泛型类型参数。

public class Util {
  public static <T> void printArray(T[] array) {
    for (T element : array) {
      System.out.println(element);
    }
  }
}

这是一个打印数组元素的泛型方法,在使用时需要传入一个泛型数组。

泛型的通配符

Java 泛型中还引入了通配符,用以表示未知类型的参数。

无限制通配符

无限制通配符使用 <?> 来表示。

public void process(List<?> list) {
  for (Object obj : list) {
    // do something
  }
}

这里的 <?> 表示这个方法可以处理任何类型的 List,但是对于集合内容的操作只能进行基本操作,例如读取元素值。

有限制通配符

有限制通配符表示参数类型必须满足某些条件,用 <? extends T><? super T> 表示。其中,<? extends T> 表示参数类型必须是 T 类型的子类,<? super T> 表示参数类型必须是 T 类型的父类。

例如:

public void process(List<? extends Number> list) {
  for (Number n : list) {
    // do something
  }
}

这里的 <? extends Number> 表示这个方法可以处理 Number 类型的子类,但是不能处理其父类。

泛型与反射

Java 泛型与反射配合使用时会有一些问题。Java 泛型在编译时需要进行类型擦除,因此在运行时是无法获取泛型类型参数的。但是,Java 反射可以获取到泛型类型信息。

例如:

public class Box<T> {
  private T t;

  public Box() {
    Class<?> clazz = getClass();
    Type tType = clazz.getGenericSuperclass();
    ParameterizedType pt = (ParameterizedType) tType;
    Type[] types = pt.getActualTypeArguments();
    this.t = (T) ((Class) types[0]).newInstance();
  }

  public T get() {
    return t;
  }
}

这里的 getGenericSuperclass 是获取父类信息的方法,通过这个方法可以获取到泛型类型信息,再通过 newInstance 方法创建泛型对象。但这种方法需要强转类型,经过测试会抛出 ClassCastException 异常。

泛型与集合框架

Java 集合框架中的很多类都是泛型类,例如 ListSetMap 等。使用泛型类可以更加灵活地处理集合中的元素,避免类型转换等问题。

// ArrayList 定义
public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable {}

// HashMap 定义
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, java.io.Serializable {}
总结

Java 泛型是 Java 5 中引入的新特性,可以提高代码的复用率、类型安全和可读性,同时它也能和 Java 反射和集合框架配合使用,让开发变得更加高效和优雅。