gpt4 book ai didi

java - 获取参数化类的类型参数

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:26:20 25 4
gpt4 key购买 nike

我有一个类Foo<T, U>使用以下构造函数:

public Foo() {
clazz = Class<U>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[1];
}

我在构造函数中所做的是获取参数的类 U .我需要它,因为我用它来实例化那个类。

问题是当我有 Foo 的子类时它不起作用那不是它的直接子类。让我举个例子。

我有课 Bar<T> extends Foo<T, Class1> .在这里,Class1不是变量而是类。

我还有课Baz extends Bar<Class2> . Class2也是一个类,不是变量。

问题是当我尝试实例化 Baz 时失败了(Baz -> Bar<Class2> -> Foo<T, Class2>)。我得到一个 ArrayIndexOutOfBoundsException因为getActualTypeArguments()返回一个仅包含类 Class2 的数组(大小 1),我正在尝试获取数组的第二个元素。那是因为我得到了 Bar<Class2> 的参数, 而不是 Foo 的那些。

我想要的是通过某种方式修改 Foo 构造函数,以获取参数 U 中的类,无论我实例化的类是否是直接子类都无关紧要。我想我应该可以在类的层次结构中上升,直到到达 Foo 类,将其转换为 ParameterizedType 并获取参数,但我找不到方法。

有什么想法吗?

提前致谢。

最佳答案

这是一个很好的方法——它是实际获取在 Java 字节码中编译的通用类型信息的唯一方法。 Java 中泛型方面的其他一切都只是类型删除。请参阅下面似乎可行的解决方案。有四种情况:

  1. 相当复杂的继承级别
  2. 您的继承方案
  3. 类本身(clazz 将为null)
  4. 不提供实际值的子类(clazz = null)

这是代码(Test.java):

import java.lang.reflect.*;
import java.util.*;

class A<T1, T2>
{
Class<T2> clazz;

A()
{
Type sc = getClass().getGenericSuperclass();
Map<TypeVariable<?>, Class<?>> map = new HashMap<TypeVariable<?>, Class<?>>();
while (sc != null)
{
if (sc instanceof ParameterizedType)
{
ParameterizedType pt = (ParameterizedType) sc;
Type[] ata = pt.getActualTypeArguments();
TypeVariable[] tps = ((Class) pt.getRawType())
.getTypeParameters();
for (int i = 0; i < tps.length; i++)
{
Class<?> value;
if (ata[i] instanceof TypeVariable)
{
value = map.get(ata[i]);
}
else
{
value = (Class) ata[i];
}
map.put(tps[i], value);
}
if (pt.getRawType() == A.class)
{
break;
}
if (ata.length >= 1)
{
sc = ((Class) pt.getRawType()).getGenericSuperclass();
}
}
else
{
sc = ((Class) sc).getGenericSuperclass();
}
}

TypeVariable<?> myVar = A.class.getTypeParameters()[1];
clazz = map.containsKey(myVar) ? (Class<T2>) map.get(myVar) : null;
}
}

class Bar<T> extends A<T, String> {}
class Baz extends Bar<Integer> {}

class A2<T3, T1, T2> extends A<T1, T2> { }
class B<T> extends A2<Long, String, T> { }
class C extends B<Integer> { }
class D extends C { }

class Plain<T1, T2> extends A<T1, T2> {}

public class Test
{
public static void main(String[] args)
{
new D();
new Baz();
new A<String, Integer>();
new Plain<String, Integer>();
}
}

关于java - 获取参数化类的类型参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6363346/

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