Java 泛型提供了强大的泛型机制,可以在编译时检查类型安全,并且可以编写通用的代码,使得代码更加灵活和重用。除了基本的泛型用法外,还有一些高级的泛型用法,以下是一些常见的高级泛型用法:
-
泛型通配符(Wildcard):通配符用于表示未知类型,可以增加泛型的灵活性。主要包括上界通配符
<? extends T>
和下界通配符<? super T>
。通配符可以用在泛型类、方法、接口等地方。 -
泛型方法:泛型方法是在方法声明时定义泛型类型,而不是在类定义时。可以让方法根据调用时的参数类型来确定返回类型,增加方法的灵活性。
-
泛型接口:类似于泛型类,泛型接口可以定义一种通用类型,可以在接口的方法中使用泛型类型。
-
泛型类的继承:泛型类也可以进行继承,子类可以继承父类的泛型类型,并可以添加自己的泛型类型。
-
泛型限定和约束:可以使用
extends
和super
关键字来限定泛型的范围,用于实现更灵活的泛型类型限定和约束。 -
泛型擦除与反射:在运行时,Java 的泛型信息会被擦除,这就导致了泛型类型不能通过反射获取泛型信息。但是可以通过获取父类(ParameterizedType)来获取泛型信息。
当使用泛型时,虽然在运行时泛型信息会被擦除,但是可以通过获取父类(ParameterizedType)来获取泛型信息。以下是一个示例代码演示如何通过获取父类来获取泛型信息:
可以通过使用匿名类来实现。以下是一个示例代码:
package org.example.gstjava.pojo;import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;/*** 一个泛型类的示例,包含两个泛型参数 T 和 U。*/
class GenericClass<T,U> {}public class Main {/*** 主函数:演示如何通过反射获取匿名泛型类的泛型参数类型。* @param args 命令行参数(未使用)*/public static void main(String[] args) {// 创建一个匿名泛型类实例,继承自 GenericClass<String,Integer>GenericClass<String,Integer> generic = new GenericClass<String,Integer>() {};// 获取匿名类的泛型超类类型Type genericSuperclass = generic.getClass().getGenericSuperclass();// 检查获取的类型是否为参数化类型if (genericSuperclass instanceof ParameterizedType) {// 将泛型超类类型转为 ParameterizedType 接口实例,以便访问其参数ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass;// 获取实际的泛型参数类型数组Type[] typeArguments = parameterizedType.getActualTypeArguments();// 遍历并打印所有泛型参数的类型名称if (typeArguments.length > 0) {for(Type type:typeArguments){System.out.println("Type: " + type.getTypeName());}} else {// 如果没有泛型参数,打印相应信息System.out.println("Type: No type arguments");}} else {// 如果获取的类型不是参数化类型,打印相应信息System.out.println("Type: Not a parameterized type.");}}
}
在示例中,我们使用了匿名类 new GenericClass<String>() {}
来创建 GenericClass
的实例,这样我们就可以通过 getClass().getGenericSuperclass()
获取到超类的 ParameterizedType
。这样可以确保 typeArguments.length
大于0,从而使 if (typeArguments.length > 0)
这个条件成立。希望这个示例能够满足您的要求。如果有任何问题,请随时告诉我。
-
泛型数组:在 Java 中创建泛型数组是不合法的,但是可以使用通配符或 Array.newInstance() 方法来创建泛型数组。
-
泛型类型推断:在 Java 7 中引入了钻石操作符
<>
,可以省略泛型类型的声明,编译器会根据上下文自动推断泛型类型。
这些是一些常见的高级泛型用法,通过灵活运用泛型机制,可以使代码更加通用和安全。在实际开发中,合理利用泛型能够提高代码的质量和扩展性。
以下是针对上述8个高级泛型用法的示
例代码:
- 泛型通配符(Wildcard):
public void printList(List<?> list) {for (Object element : list) {System.out.println(element);}
}
- 泛型方法:
public <T> T add(T a, T b) {return a + b; //这里仅作举例,实际上加法不适用于泛型,应该改用其他方式
}
- 泛型接口:
interface MyInterface<T> {void doSomething(T item);
}
- 泛型类的继承:
class GenericClass<T> {T value;
}class SubClass<T> extends GenericClass<T> {// 子类可以继承父类的泛型类型
}
- 泛型限定和约束:
public <T extends Number> void processNumber(T number) {// 只能传入 Number 及其子类
}
- 泛型擦除与反射:
class MyClass<T> {private Class<T> type;public MyClass(Class<T> type) {this.type = type;}
}MyClass<String> myObject = new MyClass<>(String.class);
- 泛型数组:
List<?>[] arrayOfLists = new List<?>[2];
arrayOfLists[0] = new ArrayList<>();
arrayOfLists[1] = new LinkedList<>();
- 泛型类型推断:
List<String> list = new ArrayList<>(); // 使用了钻石操作符
import java.util.*;public class Main {public static void main(String[] args) {// 泛型通配符示例List<String> stringList = new ArrayList<>();stringList.add("Hello");stringList.add("World");printList(stringList);// 泛型方法示例Integer sum = add(10, 20);System.out.println("Sum: " + sum);// 泛型接口示例MyInterface<String> myInterface = new MyImplementation<>();myInterface.doSomething("Generic Interface");// 泛型类的继承示例SubClass<Integer> subClass = new SubClass<>();subClass.value = 100;System.out.println("Value: " + subClass.value);// 泛型限定和约束示例processNumber(10);// 泛型擦除与反射示例MyClass<String> myObject = new MyClass<>(String.class);System.out.println("Type: " + myObject.type.getName());// 泛型数组示例List<?>[] arrayOfLists = new List<?>[2];arrayOfLists[0] = new ArrayList<>();arrayOfLists[1] = new LinkedList<>();System.out.println("Array Size: " + arrayOfLists.length);// 泛型类型推断示例List<String> list = new ArrayList<>();list.add("Java Generics");System.out.println("List: " + list.get(0));}public static void printList(List<?> list) {for (Object element : list) {System.out.println(element);}}public static <T> T add(T a, T b) {return a; // 这里仅作举例}interface MyInterface<T> {void doSomething(T item);}static class MyImplementation<T> implements MyInterface<T> {@Overridepublic void doSomething(T item) {System.out.println("Doing something with: " + item);}}static class GenericClass<T> {T value;}static class SubClass<T> extends GenericClass<T> {// 子类可以继承父类的泛型类型}public static <T extends Number> void processNumber(T number) {System.out.println("Number is: " + number);}static class MyClass<T> {private Class<T> type;public MyClass(Class<T> type) {this.type = type;}}
}