为什么 Java 需要泛型?

java 8object oriented programmingprogramming更新于 2025/11/7 5:00:17

引用类型

众所周知,类是定义所需行为和属性的蓝图;接口与类类似,但它是一种规范(包含抽象方法)。

在 Java 中,这些也被视为数据类型。与其他原始数据类型不同,这类类型的字面量指向/引用对象的位置。它们也称为引用类型。

泛型

泛型是 Java 中的一个概念,它允许类、接口和方法接受所有(引用)类型作为参数。换句话说,它允许用户动态选择类的方法(构造函数)所接受的引用类型。

通过定义类的泛型,您可以使其成为类型安全的,即它可以作用于任何数据类型。为了理解泛型,我们来看一个例子 −

示例

在下面的 Java 示例中,我们定义了一个名为 Student 的类,其构造函数(带参数)接受一个 Integer 对象。实例化此类时,您可以传递一个整数对象

class Student{
   Integer age;
   Student(Integer age){
      this.age = age;
   }
   public void display() {
      System.out.println("Value of age: "+this.age);
   }
}
public class GenericsExample {
   public static void main(String args[]) {
      Student std = new Student(25);
      std.display();
   }
}

输出

Value of age: 25

将任何其他对象传递给此类的构造函数都会生成编译时异常

public static void main(String args[]) {
   Student std = new Student("25");
   std.display();
}

编译时错误Compile

GenericsExample.java:12: error: incompatible types: String cannot be converted to Integer
   Student std = new Student("25");
                              ^
Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output
1 error

学生的年龄可以作为字符串值、浮点数、双精度数等(对象)传递。如果要传递其他对象的值,则需要将构造函数更改为 −

class Student{
   String age;
   Student(String age){
      this.age = age;
   }
}
或者,
class Student{
   Float age;
   Student(Float age){
      this.age = age;
   }
}

声明泛型类型时,它们可以作用于任何数据类型,因此被称为参数化类型。泛型中不能使用原始数据类型。

创建泛型类型

使用泛型参数 T 或 GT 作为 − 创建泛型类型的类

class Student <T>{
   T obj;
}

其中 T(泛型参数)表示可以传递给此类构造函数的对象的数据类型。这将在编译时确定。

在实例化类时,您需要/可以选择将泛型参数的类型设置为 −

Student<Float> obj = new Student<Float>();

示例

我们可以使用泛型将上述示例重写为 −

class Student<T>{
   T age;
   Student(T age){
      this.age = age;
   }
   public void display() {
      System.out.println("Value of age: "+this.age);
   }
}
public class GenericsExample {
   public static void main(String args[]) {
      Student<Float> std = new Student<Float>(25.5f);
      std.display();
   }
}

输出

Value of age: 25.5

现在,在实例化 Student 类时,您可以将所需类型的对象作为参数传递,如下所示 −

class Student<T>{
   T age;
   Student(T age){
      this.age = age;
}
   public void display() {
      System.out.println("Value of age: "+this.age);
   }
}
public class GenericsExample {
   public static void main(String args[]) {
      Student<Float> std1 = new Student<Float>(25.5f);
      std1.display();
      Student<String> std2 = new Student<String>("25");
      std2.display();
      Student<Integer> std3 = new Student<Integer>(25);
      std3.display();
   }
}

输出

Value of age: 25.5
Value of age: 25
Value of age: 25

为什么我们需要泛型

在代码中使用泛型将获得以下优势 −

  • 编译时进行类型检查 −通常,当您使用类型(常规对象)时,如果传递了错误的对象作为参数,则会在运行时提示错误。

  • 而当您使用泛型时,错误会在编译时发生,这很容易解决。

  • 代码重用 −您可以使用泛型类型编写一次方法、类或接口,然后可以使用各种参数多次使用此代码。

  • 对于某些类型,使用正式类型时,您需要强制转换对象并使用。使用泛型(大多数情况下),您可以直接传递所需类型的对象,而无需依赖强制类型转换。

  • 使用泛型,您可以实现各种泛型算法。


相关文章