仅在运行时知道类型时使用Javagenerics

请考虑以下代码:

public class Generics { C c; // initialized at runtime public void testGenericsCall(Object o) { c.myMethod(o); } } class C { public void myMethod(E input) { } } 

这是有效的,但我收到警告,因为参数化的类C与原始类型一起使用。 我不能使用像这样的声明

 C c; 

因为C的类型仅在运行时才知道。 我也无法在类Generics中添加类型参数,因为我需要在知道C类型之前创建此类的对象。

 C c; 

要么

 C c; 

对于编译器来说没关系,但是然后方法testGenericsCall不能编译( “实际参数java.lang.Object无法通过方法调用转换转换为捕获#1?”

处理这种情况的最佳方法是什么?

编辑 :请注意,当我实际(在运行时)创建C的实例时,我知道它的类型参数,这部分代码是类型安全的并且运行良好。 在实际代码中,我没有一个单独的“C”类,而是一系列相互关联的类,并且generics绝对有用(即使在这个简化的例子中这并不明显 – 所以请不要只告诉我不要使用generics:)。 我已经有了编译时类型安全,但不是在这里,而是在C和其他类之间(这里没有显示)。

我看到在这种情况下我不能在编译时检查类型参数,这就是为什么我试图声明它C c 。 在这里, 我只是寻找在没有编译器警告的情况下桥接通用和非通用代码的最佳方法。

由于类型擦除 ,在运行时无法使用generics。 您必须通过检查类型或任何内容(可能是reflection)以编程方式处理您的数据类型。

你能行的。 但通过肮脏的技巧和反思。 以下面的代码为例。 礼貌在这里 :

 class ParameterizedTest { /** * @return the type parameter to our generic base class */ @SuppressWarnings("unchecked") protected final Class determineTypeParameter() { Class specificClass = this.getClass(); Type genericSuperclass = specificClass.getGenericSuperclass(); while (!(genericSuperclass instanceof ParameterizedType) && specificClass != ParameterizedTest.class) { specificClass = specificClass.getSuperclass(); genericSuperclass = specificClass.getGenericSuperclass(); } final ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass; final Type firstTypeParameter = parameterizedType.getActualTypeArguments()[0]; return (Class) firstTypeParameter; } } //change the type of PrameterizedTest to Parameterized or something to display different output public class Test extends ParameterizedTest{ public static void main(String... args){ Test test = new Test(); System.out.println(test.determineTypeParameter()); } 

}

在运行时,您将获得Type参数。 因此,在您的类中,您将必须定义一个Class对象,该对象获取如上所述的类。 然后使用Class.newInstance获得一个新的Object。 但是你必须手动处理类型转换等等。

问题是:这一切都值得吗?

不,根据我,因为大多数可以通过使用generics类型中的边界和接口绑定类型来避免