Java 泛型使我们能够创建一个可以与不同类型数据(对象)一起使用的单个类、接口和方法。
这有助于我们重用代码。
注意:泛型不适用于基本类型(int
、float
、char
等)。
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 只能处理 Number
(Integer
、Double
等)的子类型数据。
但是,我们用 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 中的其他集合(LinkedList
、Queue
、Maps
等)也支持泛型。