使用反射和泛型时警告

时间:2013-01-02 10:36:32

标签: java generics reflection

我如何重写:

<T> T callMethod(String methodName, Object[] parameters) throws ... {
    ...
    return (T) SomeClass.class.getDeclaredMethod(methodName, parameterTypes).invoke(binding, parameters);
}

因此它不会生成警告

warning: [unchecked] unchecked cast
        return (T) SomeClass.class.getDeclaredMethod(methodName, parameterTypes).invoke(binding, parameters);
required: T
found:    Object
where T is a type-variable:
T extends Object declared in method <T>callMethod(String,Object[])

我指的是无SupressWarnings解决方案。

5 个答案:

答案 0 :(得分:5)

我认为您必须使用@SuppressWarnings(...)方法,因为invoke() method会返回Object。请记住,泛型在运行时被擦除,并且反射在运行时发生......

干杯,

答案 1 :(得分:3)

编译器无法在编译时确定您在运行时选择的方法的返回类型为T.您只能在编译时禁止警告。

答案 2 :(得分:3)

正如Peter Lawrey pointed out

  

编译器无法在编译时确定   您在运行时选择的方法的返回类型为T

我会更进一步说callMethod根本不应该是一般的方法。由于调用者通过将其名称作为字符串传递来决定调用哪个方法,因此该方法应该返回Object - 如invoke - 并强制调用调用站点。

不要使用@SuppressWarnings - 这里没有办法证明这一点。

答案 3 :(得分:2)

为此,您必须在方法参数中声明结果类型。

public <T> T callMethod(Class<T> resultType, String methodName, Object[] parameters) {

Object result = SomeClass.class.getDeclaredMethod(methodName, parameterTypes).invoke(binding, parameters);

if(resultType.isInstance(result)) {
  return resultType.cast(result);
}

throw new ClassCastException("Invalid result type");

}

你为什么要这样做?

见彼得L.回答。

答案 4 :(得分:0)

您尚未使用@SuppressWarnings("unchecked")注释。

@SuppressWarnings("unchecked")只能应用于对象的声明,这将起作用: