在泛型中,常见的字母表示法通常用于表示类型参数,它们没有固定含义,但在惯例中被广泛使用。以下是通常用于表示泛型类型参数的一些常见字母及其惯例含义:
- T: 表示任意类型。通常用于表示泛型方法或泛型类中的类型参数。
- K: 表示键(Key)。通常用于表示键值对中的键的类型。
- V: 表示值(Value)。通常用于表示键值对中的值的类型。
- E: 表示元素(Element)。通常用于表示集合中的元素类型。
- N: 表示数字(Number)。通常用于表示数字类型,如整数、浮点数等。
- S,U,V 等: 用于表示第二、第三、第四个泛型类型参数。
这些字母并没有固定的含义,但是它们在代码中的使用已经成为了一种约定俗成的规范,有助于提高代码的可读性和理解性。
1. 泛型方法(Generic Methods)
public class GenericMethods {
// 泛型方法示例
public <T> void printArray(T[] inputArray) {
for (T element : inputArray) {
System.out.printf("%s ", element);
}
System.out.println();
}
}
2. 泛型类(Generic Classes)
public class Box<T> {
private T value;
public void setValue(T value) {
this.value = value;
}
public T getValue() {
return value;
}
}
3. 泛型接口(Generic Interfaces)
public interface Pair<K, V> {
K getKey();
V getValue();
}
4. 通配符(Wildcards)
public void printList(List<?> list) {
for (Object obj : list) {
System.out.print(obj + " ");
}
System.out.println();
}
5. 有界泛型(Bounded Generics)
public double sumOfList(List<? extends Number> list) {
double sum = 0.0;
for (Number num : list) {
sum += num.doubleValue();
}
return sum;
}
示例
import java.util.List;
import java.util.Map;
// 泛型方法示例
public class ComplexGenericExample<T, U> {
// 泛型方法示例
public <E, V> void printArray(E[] inputArray, V[] secondArray) {
System.out.print("First Array: ");
for (E element : inputArray) {
System.out.printf("%s ", element);
}
System.out.println();
System.out.print("Second Array: ");
for (V element : secondArray) {
System.out.printf("%s ", element);
}
System.out.println();
}
// 泛型接口示例
public interface Pair<K, V> {
K getKey();
V getValue();
}
// 实现多个泛型接口
public class ComplexPair<K, V, S> implements Pair<K, V>, Comparable<S> {
private K key;
private V value;
public ComplexPair(K key, V value) {
this.key = key;
this.value = value;
}
public K getKey() {
return key;
}
public V getValue() {
return value;
}
@Override
public int compareTo(S o) {
// 实现 Comparable 接口的比较方法
return 0;
}
}
// 通配符示例
public void printList(List<? extends Number> list, List<? super String> secondList) {
System.out.print("First List: ");
for (Number number : list) {
System.out.print(number + " ");
}
System.out.println();
System.out.print("Second List: ");
for (Object obj : secondList) {
System.out.print(obj + " ");
}
System.out.println();
}
// 有界泛型示例
public double sumOfList(List<? extends Number> list, List<? super Integer> secondList) {
double sum = 0.0;
for (Number num : list) {
sum += num.doubleValue();
}
secondList.add((int) sum);
return sum;
}
// 主方法
public static void main(String[] args) {
// 泛型类实例化
ComplexGenericExample<Double, String> complexGenericExample = new ComplexGenericExample<>();
// 泛型方法调用
Integer[] intArray = { 1, 2, 3, 4, 5 };
String[] stringArray = { "Hello", "World" };
complexGenericExample.printArray(intArray, stringArray);
// 实现多个泛型接口
ComplexPair<Integer, String, Double> complexPair = complexGenericExample.new ComplexPair<>(1, "One");
System.out.println("Key: " + complexPair.getKey() + ", Value: " + complexPair.getValue());
// 使用通配符的方法调用
List<Integer> intList = List.of(1, 2, 3, 4, 5);
List<String> stringList = new ArrayList<>();
complexGenericExample.printList(intList, stringList);
// 使用有界泛型的方法调用
List<Double> doubleList = List.of(1.1, 2.2, 3.3, 4.4, 5.5);
List<Integer> integerList = new ArrayList<>();
double sum = complexGenericExample.sumOfList(doubleList, integerList);
System.out.println("Sum of list: " + sum);
System.out.println("Integer List: " + integerList);
}
}
补充: 无法直接创建泛型数组
Box<String>[] arrayOfBoxes = new Box<String>[5]; // 这是错误的!无法创建泛型数组
为什么会出错呢?因为 Java 编译器无法确定 arrayOfBoxes
数组的确切类型。在运行时,泛型信息会被擦除,所以编译器无法保证数组的元素类型是 Box<String>
。如果允许创建这样的数组,那么可能会导致类型安全问题,例如你可以向数组中添加一个不同类型的对象,从而违反了泛型的类型安全性。
可以使用如下方法
import java.lang.reflect.Array;
public class Main {
public static void main(String[] args) {
// 创建一个长度为 5 的 Box<String> 类型的数组
Box<String>[] arrayOfBoxes = createArray(Box.class, 5);
// 初始化数组的每个元素
for (int i = 0; i < arrayOfBoxes.length; i++) {
arrayOfBoxes[i] = new Box<String>("Item " + i);
}
// 打印数组的每个元素
for (Box<String> box : arrayOfBoxes) {
System.out.println(box.getItem());
}
}
// 泛型方法,用于创建泛型数组
@SuppressWarnings("unchecked")
public static <T> T[] createArray(Class<T> type, int length) {
return (T[]) Array.newInstance(type, length);
}
}
// 泛型类 Box
class Box<T> {
private T item;
public Box(T item) {
this.item = item;
}
public T getItem() {
return item;
}
}
Array.newInstance()
方法可以用于创建任意类型的数组,包括泛型数组。它接受两个参数:数组元素的类型和数组的长度。通过传入数组元素的类对象,可以在运行时创建一个与该类对象对应的数组。
在 Java 中,泛型的类型信息在编译时会被擦除,这就意味着编译器无法直接创建泛型数组,因为它无法确定泛型的确切类型。但是,通过 Array.newInstance()
方法,可以在运行时提供泛型类型的信息,从而动态地创建泛型数组。