Java 泛型定义格式与应用

Java泛型(Generics)是Java SE 5引入的一项核心语言功能,是一种用于在编译时对类型进行检查的技术,它允许程序员在编写接口方法时使用类型参数(type parameters),而不是硬编码具体的类型。

这样做可以让代码更加灵活和可复用,同时增强了类型安全性,能够在编译阶段捕获类型不匹配的错误,减少运行时错误。

基础概念

  • 类型参数:在定义泛型类或方法时,可以使用尖括号 < > 中的类型参数表示待定的类型。
    • 例如,List<T> 中的 T 就是一个类型参数,当你创建一个 List 实例时,可以指定 T 为任何有效类型,如 List<String>List<Integer>
  • 类型约束:类型参数可以带有约束条件,表明它必须是某种特定类型或者其子类型。
    • 例如,T extends Comparable<T> 表示 T 必须是实现了 Comparable<T> 接口的类型。
  • 泛型方法:不只是类可以使用泛型,方法也可以拥有自己的类型参数,使方法独立于类的泛型类型。

优势

  • 类型安全:通过在编译时就进行类型检查,可以防止插入错误类型的元素,从而降低运行时出现 ClassCastException 的风险。
  • 代码复用:通过泛型,可以编写一个通用的类或方法,适用于多种数据类型,避免为每种类型都编写重复的代码。

定义格式

泛型的定义格式主要包括在类、接口、方法和数组中定义泛型类型参数。

定义泛型类

  • 修饰符 class 类名<类型> { }:泛型类通过在其名称后面使用尖括号 < > 内指定类型参数来定义。例如,定义一个名为 Box 的泛型类,其中的 T 表示任意类型:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
java复制代码// 定义一个泛型类
public class Box<T> {
private T item;

public Box(T item) {
this.item = item;
}

public T getItem() {
return item;
}

public void setItem(T item) {
this.item = item;
}
}

// 使用泛型类
Box<String> stringBox = new Box<>("Hello");
Box<Integer> integerBox = new Box<>(123);

定义泛型接口

  • 修饰符 interface 接口名<类型> { }:泛型接口的定义方式与泛型类类似,同样在接口名称后使用尖括号 < > 指定类型参数:
1
2
3
4
5
6
7
8
9
10
11
12
java复制代码// 定义一个泛型接口
public interface Generator<T> {
T generate();
}

// 实现泛型接口
public class StringGenerator implements Generator<String> {
@Override
public String generate() {
return "Generated String";
}
}

定义泛型方法

  • 修饰符 <类型> 返回值类型 方法名(类型 变量名) { }:泛型方法是在方法签名中声明类型参数,不受类级别的泛型参数影响:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
java复制代码public class Util {
public static <T> void printArray(T[] array) {
for (T item : array) {
System.out.println(item);
}
}
}

// 使用泛型方法
Integer[] integers = {1, 2, 3};
Util.printArray(integers);

String[] strings = {"Hello", "World"};
Util.printArray(strings);

泛型类型的边界(类型约束)

  • 可以通过 extendssuper 关键字来指定类型参数的边界,限制它可以是某种类型或其子类/父类:
1
2
3
4
5
6
7
8
9
10
11
12
java复制代码public class ComparableBox<T extends Comparable<T>> {
private T item;

// ... methods ...

public int compare(T other) {
return item.compareTo(other);
}
}

// 使用带边界约束的泛型类
ComparableBox<String> comparableStringBox = new ComparableBox<>("abc");

通配符类型

  • <?>:通配符类型用于更灵活的类型匹配,主要有两种形式:
    • ? 表示未知类型;
    • ? extends SomeType 表示某种类型的子类型;
    • ? super SomeType 表示某种类型的父类型;
1
2
3
4
5
6
7
8
9
10
11
java复制代码public void processElements(List<?> list) {
for (Object obj : list) {
System.out.println(obj);
}
}

// 使用通配符类型的泛型方法
List<String> stringList = new ArrayList<>();
processElements(stringList);
List<Integer> integerList = new ArrayList<>();
processElements(integerList);

注意事项

  • 泛型只能用于引用类型,不能用于基本数据类型。例如,不能有List<int>,而应该使用List<Integer>
  • 泛型类或接口不能有泛型类型的实例字段,因为这样的字段在运行时无法确定具体类型。
  • 泛型的类型擦除:Java泛型在编译时提供类型检查,在运行时不保留泛型类型信息。这意味着泛型类型信息在运行时会被擦除。

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%