1

考虑以下代码:

public class Generics {
    C c; // initialized at runtime

    public void testGenericsCall(Object o) {
        c.myMethod(o);
    }
}

class C<E> {
    public void myMethod(E input) {
    }
}

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

C<String> c;

因为只有在运行时才知道 C 的类型。我也无法向泛型类添加类型参数,因为我需要在知道 C 的类型之前创建此类的对象。声明

C<?> c;

或者

C<? extends Object> c;

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

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

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

我看到在这种情况下我无法在编译时检查类型参数,这就是我尝试声明它的原因 C<?> c。在这里,我只是在寻找在没有编译器警告的情况下桥接通用代码和非通用代码的最佳方法。

4

2 回答 2

3

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

于 2013-02-19T10:56:26.843 回答
2

你能行的。但是通过肮脏的伎俩和反思。例如看下面的代码。礼貌在这里

class ParameterizedTest<T> {

/**
 * @return the type parameter to our generic base class
 */
@SuppressWarnings("unchecked")
protected final Class<T> 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<T>) firstTypeParameter;
}



}

//change the type of PrameterizedTest<Integer> to Parameterized<String> or something to    display different output
public class Test extends ParameterizedTest<Integer>{
 public static void main(String... args){
    Test test = new Test();
    System.out.println(test.determineTypeParameter());
}

}

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

问题是:这一切值得吗?

根据我的说法不,因为可以通过在泛型类型中使用边界并与绑定类型接口来避免大多数情况

于 2013-02-20T06:12:29.220 回答