我有一个Foo<T, U>具有以下构造函数的类:
public Foo() {
clazz = Class<U>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[1];
}
Run Code Online (Sandbox Code Playgroud)
我在构造函数中做的是获取参数的类U.我需要它,因为我用它来实例化那个类.
问题是,当我的子类Foo不是它的直接sublcass时,它不起作用.让我举一个例子.
我上课了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 中泛型的其他内容都只是类型擦除。请参阅下面似乎是可行的解决方案。有四种情况:
clazz将是null)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>();
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4144 次 |
| 最近记录: |