泛型
1.什么是泛型
在Java中,泛型(Generics)是Java 5(也称为Java SE 5.0或JDK 1.5)中引入的一个重要特性,它提供了一种编译时类型安全检测机制,允许程序员在类、接口和方法中使用类型参数(Type Parameters)。这些类型参数在编译时会被具体的类型所替换,从而实现了代码的复用和类型安全。
泛型的定义
泛型,即“参数化类型”,其本质是将类型参数化。在定义类、接口或方法时,可以将类型作为参数传递,并在使用时指定具体的类型。这样做的好处是可以在编译时期检查数据类型的合法性,避免运行时类型错误,同时提高代码的可读性、可维护性和复用性。
2.泛型的作用
Java中的泛型主要应用于以下几个方面:
- 泛型类:
- 在定义类时,可以在类名后使用尖括号
<>
包含类型参数。这些类型参数在类内部可以作为成员变量的类型、方法的返回类型或参数类型。 - 示例:
public class Box<T> { private T t; public void set(T t) { this.t = t; } public T get() { return t; } }
- 在定义类时,可以在类名后使用尖括号
- 泛型接口:
- 与泛型类类似,接口也可以定义类型参数。实现接口的类在实例化时需要指定这些类型参数的具体类型。
- 示例:
public interface Pair<K, V> { K getKey(); V getValue(); }
- 泛型方法:
- 泛型方法允许在方法签名中声明类型参数,这些类型参数在方法体内作为返回类型或参数类型使用。
- 示例:
public static <T> void printArray(T[] inputArray) { for (T element : inputArray) { System.out.printf("%s ", element); } System.out.println(); }
- 通配符(Wildcards):
- 通配符用于表示某个泛型类型的子类型或超类型,常用于泛型集合的声明和操作中。
- 示例:
List<?> list
表示一个未知类型的列表,List<? extends Number> list
表示一个元素类型为Number或其子类型的列表。
- 有界泛型(Bounded Generics):
- 有界泛型是对泛型类型参数进行限制的一种方式,可以使用
extends
关键字表示类型参数的上界,使用super
关键字表示类型参数的下界。 - 示例:
public <T extends Comparable<T>> T findMax(T[] a)
表示方法findMax
接受一个实现了Comparable
接口的数组,并返回数组中的最大值。
- 有界泛型是对泛型类型参数进行限制的一种方式,可以使用
3.泛型的特性
- 类型安全:在编译时期进行类型检查,避免运行时类型错误。
- 消除类型转换:使用泛型后,可以在编译时期自动进行类型转换,减少代码中的显式类型转换。
- 提高代码复用性:通过类型参数化,可以编写更加通用的代码,提高代码的复用性。
- 提高代码可读性:使用泛型可以使代码更加清晰、易于理解。
4.泛型的使用
4.1. 泛型类
泛型类就是在类定义时通过类型参数指定类中某些成员的类型。类型参数在类名后的尖括号<>
中声明。
public class Box<T> {
private T t;
public void set(T t) {
this.t = t;
}
public T get() {
return t;
}
}
// 使用泛型类
Box<Integer> integerBox = new Box<>();
integerBox.set(123);
Integer value = integerBox.get();
Box<String> stringBox = new Box<>();
stringBox.set("Hello");
String str = stringBox.get();
4.2. 泛型接口
泛型接口与泛型类类似,也是在接口定义时通过类型参数来指定接口中某些方法的返回类型或参数类型。
public interface Pair<K, V> {
K getKey();
V getValue();
}
// 实现泛型接口
public class SimplePair<K, V> implements Pair<K, V> {
private K key;
private V value;
public SimplePair(K key, V value) {
this.key = key;
this.value = value;
}
@Override
public K getKey() {
return key;
}
@Override
public V getValue() {
return value;
}
}
// 使用泛型接口
Pair<String, Integer> pair = new SimplePair<>("Key", 123);
String key = pair.getKey();
Integer value = pair.getValue();
4.3. 泛型方法
泛型方法允许你在方法签名中声明类型参数,这些类型参数在方法体内作为返回类型或参数类型使用。
public class Util {
// 泛型方法
public static <T> void printArray(T[] inputArray) {
for (T element : inputArray) {
System.out.printf("%s ", element);
}
System.out.println();
}
}
// 使用泛型方法
Integer[] intArray = {1, 2, 3, 4, 5};
Util.printArray(intArray);
String[] stringArray = {"Hello", "World", "Generics"};
Util.printArray(stringArray);
4.4. 泛型集合
Java集合框架(Collections Framework)在Java 5及以后版本中广泛使用了泛型。使用泛型集合可以避免在运行时出现ClassCastException
,并提供了编译时类型安全。
import java.util.ArrayList;
import java.util.List;
// 使用泛型集合
List<String> stringList = new ArrayList<>();
stringList.add("Hello");
stringList.add("World");
// 尝试添加非String类型对象将导致编译错误
// stringList.add(123); // 编译错误
for (String str : stringList) {
System.out.println(str);
}
4.5. 泛型通配符
泛型通配符(Wildcards)用于表示某个泛型类型的子类型或超类型。它们主要用于泛型集合的声明和操作中。
List<?> unknownList = new ArrayList<String>();
// unknownList.add("Hello"); // 编译错误,因为类型未知
List<? extends Number> numberList = new ArrayList<Integer>();
// numberList.add(123); // 编译错误,因为? extends Number是一个上界通配符
Number n = numberList.get(0); // 假设numberList不为空
List<? super Integer> superIntList = new ArrayList<Integer>();
superIntList.add(123); // 正确,因为? super Integer是一个下界通配符
标签:编译,接口,类型,参数,泛型,public
From: https://www.cnblogs.com/tubby233/p/18347062