gpt4 book ai didi

java - 在运行时 : works in some cases, 获取泛型类型,但在其他运行时获取泛型类型 - 为什么?

转载 作者:行者123 更新时间:2023-11-30 10:57:11 24 4
gpt4 key购买 nike

我正在尝试获取类或接口(interface)实现的通用类型。我知道这有一些风险和怪癖,但我试图了解什么是可能的。

这是我的示例代码:

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.LinkedList;

public class Main {

public interface MyInterface<T> {
}

public static class BaseImpl<T> implements MyInterface<T> {
}

public static class TypedImpl extends BaseImpl<Integer> {
}

public static void main(String[] args) throws Exception {
LinkedList<MyInterface<Integer>> instances = new LinkedList<>();

// 1. anonymous class from interface
instances.add(new MyInterface<Integer>() {
});

// 2. class extending interface
instances.add(new BaseImpl<Integer>());

// 3. class with pre-defined generic type
instances.add(new TypedImpl());

for (MyInterface<Integer> instance : instances) {
System.out.println("----------------------------------------------");

Class clazz = instance.getClass();
Type genericSuper = clazz.getGenericSuperclass();
Type[] genericInterfaces = clazz.getGenericInterfaces();
Class target = null;

System.out.println("class: " + clazz.getName());
System.out.println("generic super: " + genericSuper);
System.out.println("generic interfaces: " + Arrays.asList(genericInterfaces));

// attempt to 'extract' generic type
if (genericSuper instanceof ParameterizedType) {
target = getGeneric((ParameterizedType) genericSuper);
} else if (genericInterfaces.length > 0) {
for (Type genericInterface : genericInterfaces) {
if (genericInterface instanceof ParameterizedType) {
target = getGeneric((ParameterizedType) genericInterface);

if (null != target) {
break;
}
}
}
}

System.out.println("TARGET: " + target);
}
}

// attempt to get type argument
public static Class getGeneric(ParameterizedType type) {
if (MyInterface.class.isAssignableFrom((Class) type.getRawType())) {
Type typeArg = type.getActualTypeArguments()[0];

try {
return (Class) typeArg;
} catch (ClassCastException e) {
System.out.println("cast exception for '" + typeArg + "'");
}
}

return null;
}

}

这个的输出是:

----------------------------------------------
class: Main$1
generic super: class java.lang.Object
generic interfaces: [Main.Main$MyInterface<java.lang.Integer>]
TARGET: class java.lang.Integer
----------------------------------------------
class: Main$BaseImpl
generic super: class java.lang.Object
generic interfaces: [Main.Main$MyInterface<T>]
cast exception for 'T'
TARGET: null
----------------------------------------------
class: Main$TypedImpl
generic super: Main.Main$BaseImpl<java.lang.Integer>
generic interfaces: []
TARGET: class java.lang.Integer

因此,我的目标是让 target 变量的值为 Integer.class。对于匿名类 (#1) 和显式类型实现 (#3),我能够按预期找到目标。为什么它在这些实例中起作用而不是在#2(BaseImpl 实例)的情况下?还有另一种方法可以做到这一点吗? (我知道通过实现类的构造函数传递目标 Class 的常见解决方法,但是我对动态执行此操作很感兴趣)

我引用了以下资源:

提前致谢

阿贝尔

最佳答案

来自 http://tutorials.jenkov.com/java-reflection/generics.html (粗体是我的)

Using Java Generics typically falls into one of two different situations:

Declaring a class/interface as being parameterizable. Using a parameterizable class. When you write a class or interface you can specify that it should be paramerizable. This is the case with the java.util.List interface. Rather than create a list of Object you can parameterize java.util.List to create a list of say String.

When runtime inspecting a parameterizable type itself, like java.util.List, there is no way of knowing what type is has been parameterized to. This makes sense since the type can be parameterized to all kinds of types in the same application. But, when you inspect the method or field that declares the use of a parameterized type, you can see at runtime what type the paramerizable type was parameterized to. In short:

You cannot see on a type itself what type it is parameterized to a runtime, but you can see it in fields and methods where it is used and parameterized. Its concrete parameterizations in other words.

特殊情况在页面上解释

关于java - 在运行时 : works in some cases, 获取泛型类型,但在其他运行时获取泛型类型 - 为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32716797/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com