Java 泛型

Java 泛型使我们能够创建一个可以与不同类型数据(对象)一起使用的单个类、接口方法

这有助于我们重用代码。

注意泛型不适用于基本类型intfloatchar 等)。


Java 泛型类

我们可以创建一个可与任何类型数据一起使用的类。这样的类称为泛型类。

这是我们在 Java 中创建泛型类的方法

示例:创建泛型类

class Main {
  public static void main(String[] args) {

    // initialize generic class
    // with Integer data
    GenericsClass<Integer> intObj = new GenericsClass<>(5);
    System.out.println("Generic Class returns: " + intObj.getData());

    // initialize generic class
    // with String data
    GenericsClass<String> stringObj = new GenericsClass<>("Java Programming");
    System.out.println("Generic Class returns: " + stringObj.getData());
  }
}

// create a generics class
class GenericsClass<T> {

  // variable of T type
  private T data;

  public GenericsClass(T data) {
    this.data = data;
  }

  // method that return T type variable
  public T getData() {
    return this.data;
  }
}

输出

Generic Class returns: 5
Generic Class returns: Java Programming

在上面的示例中,我们创建了一个名为 GenericsClass 的泛型类。该类可用于处理任何类型的数据。

class GenericsClass<T> {...}

在这里, angle bracket <> 内使用的 T 表示类型参数。在 Main 类中,我们创建了两个 GenericsClass 对象

  • intObj - 在这里,类型参数 T 被替换为 Integer。现在,GenericsClass 可以处理整数数据。
  • stringObj - 在这里,类型参数 T 被替换为 String。现在,GenericsClass 可以处理字符串数据。

Java 泛型方法

与泛型类类似,我们还可以创建一个可与任何类型数据一起使用的方法。这样的类称为泛型方法。

这是我们在 Java 中创建泛型的方法

示例:创建泛型方法

class Main {
  public static void main(String[] args) {

    // initialize the class with Integer data
    DemoClass demo = new DemoClass();

    // generics method working with String
    demo.<String>genericsMethod("Java Programming");

    // generics method working with integer
    demo.<Integer>genericsMethod(25);
  }
}

class DemoClass {

  // creae a generics method
  public <T> void genericsMethod(T data) {
    System.out.println("Generics Method:");
    System.out.println("Data Passed: " + data);
  }
}

输出

Generics Method:
Data Passed: Java Programming
Generics Method:
Data Passed: 25

在上面的示例中,我们创建了一个名为 genericsMethod 的泛型方法。

public <T> void genericMethod(T data) {...}

这里,类型参数 <T> 插入在修饰符 public 之后、返回类型 void 之前。

我们可以通过在方法名前的括号中放入实际类型 <String><Integer> 来调用泛型方法。

demo.<String>genericMethod("Java Programming");

demo.<Integer>genericMethod(25);

注意:我们可以不包含类型参数来调用泛型方法。例如,

demo.genericsMethod("Java Programming");

在这种情况下,编译器可以根据传递给方法的参数值来匹配类型参数。


有界类型

通常,类型参数可以接受任何数据类型(基本类型除外)。

但是,如果我们只想使用泛型处理某些特定类型(例如,仅接受数字类型的数据),那么我们可以使用有界类型。

在有界类型的情况下,我们使用 extends 关键字。例如,

<T extends A>

这意味着 T 只能接受 A 的子类型数据。

示例:有界类型

class GenericsClass <T extends Number> {

  public void display() {
    System.out.println("This is a bounded type generics class.");
  }
}

class Main {
  public static void main(String[] args) {

    // create an object of GenericsClass
    GenericsClass<String> obj = new GenericsClass<>();
  }
}

在上面的示例中,我们创建了一个名为 GenericsClass 的类。注意表达式,注意表达式

<T extends Number> 

这里,GenericsClass 是用有界类型创建的。这意味着 GenericsClass 只能处理 NumberIntegerDouble 等)的子类型数据。

但是,我们用 String 创建了一个泛型类的对象。在这种情况下,我们会得到以下错误。

GenericsClass<String> obj = new GenericsClass<>();
                                                 ^
    reason: inference variable T has incompatible bounds
      equality constraints: String
      lower bounds: Number
  where T is a type-variable:
    T extends Number declared in class GenericsClass

Java 泛型的优点

1. 代码可重用性

借助 Java 中的泛型,我们可以编写适用于不同类型数据的代码。例如,

public <T> void genericsMethod(T data) {...}

在这里,我们创建了一个泛型方法。此方法可用于对整数数据、字符串数据等执行操作。

2. 编译时类型检查

泛型的类型参数提供了关于泛型代码所用数据类型的信息。例如,

// using Generics
GenericsClass<Integer> list = new GenericsClass<>();

这里,我们知道 GenericsClass 只处理 Integer 数据。

现在,如果我们尝试将 Integer 以外的数据传递给此类,程序将在编译时生成错误。

3. 与集合一起使用

集合框架在 Java 中使用了泛型的概念。例如,

// creating a string type ArrayList
ArrayList<String> list1 = new ArrayList<>();

// creating a integer type ArrayList
ArrayList<Integer> list2 = new ArrayList<>();

在上面的示例中,我们使用了相同的 ArrayList 类来处理不同类型的数据。

ArrayList 类似,Java 中的其他集合(LinkedListQueueMaps 等)也支持泛型。

你觉得这篇文章有帮助吗?

我们的高级学习平台,凭借十多年的经验和数千条反馈创建。

以前所未有的方式学习和提高您的编程技能。

试用 Programiz PRO
  • 交互式课程
  • 证书
  • AI 帮助
  • 2000+ 挑战