我有一个带有集合吸气剂的课程,我通过反思进行检查。像这样:
class Bar {
String baz;
int bazooka;
}
class Foo {
List<Bar> bars = new ArrayList<Bar>();
List<Bar> getBarsList() { return bars; }
}
我需要在运行时找到的是类对象Class<Bar>
。我知道如果您引用Field
对象,则可能。但是它也可能来自getter Method
?
答案 0 :(得分:4)
在您的情况下,可以使用反射。您不能做的是获取有关类型的运行时信息。给定一个参数化类型的实例,您无法在运行时找出参数化的内容。这是其他答案告诉你的,但这不是你要问的。你问的是编译时类型约束。
public class Test {
public static void main(String args[]) throws NoSuchMethodException {
Method method = Foo.class.getDeclaredMethod("getBars", new Class[]{});
Type grt = method.getGenericReturnType();
if (grt instanceof ParameterizedType) {
Type Bar = ((ParameterizedType) grt).getActualTypeArguments()[0];
System.out.println(Bar);
}
}
}
class Foo {
List<Bar> getBars() {
return Collections.emptyList();
}
}
class Bar {
}
打印class com.package.Bar
如果另一方面你有这样的课程:
class Foo<T> {
List<T> getBars() {
return Collections.emptyList();
}
}
然后你无法在运行时获得T的Foo实例。存在变通方法,其中人们创建具有固定类型参数的匿名子类。
答案 1 :(得分:1)
由于两个原因,该信息在运行时不存在:
1)那里不需要它。这是对编译器的暗示,并符合您的强类型方法。
2)Java使用泛型类型擦除来保持与预泛类型的兼容性。
你可以但是以另一种方式执行此操作(愚蠢,但如果代码是您的,则可以使用):
class MyGenericClass extends ArrayList<MyObject> {
// Check the class for this variable name. Its type will indicate the generic type.
// Alternatively we can use the type class instance directly.
final static MyObject mGenericType = null;
final static Class mGenericTypeClass = MyObject.getClass();
}
我知道这是一个部分解决方案(如果有任何解决方案),但是,如果你真的需要这个,那么总比没有好。
再想一想,有一种简单的方法可以做到这一点。您可以使用参数创建一个可保留的注释,该参数将提供有关注释类/字段的泛型类型的信息。