代码之家  ›  专栏  ›  技术社区  ›  gdejohn

在Java中强制转换为泛型方法类型变量时出现编译器警告

  •  4
  • gdejohn  · 技术社区  · 15 年前

    编辑: 我最初接受了jh的答案,但我并不太满意,因为我想正确使用泛型。所以,我一直在做研究,找到了解决办法。在中阅读 my answer 下面。


    下面是一段自包含的Java代码,它展示了我要做的事情。它编译、运行和行为正确。

     1 import java.lang.reflect.Method;
     2 import java.lang.reflect.InvocationTargetException;
     3 
     4 public class Example
     5 {
     6    public static <T> void foo(Method method, String target, Object argument, T expectedReturn) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException
     7    {
     8       T actualReturn = (T) method.invoke(target, argument);
     9       System.out.print(actualReturn.equals(expectedReturn));
    10    }
    11    
    12    public static void main(String[ ] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException
    13    {
    14       foo(String.class.getMethod("charAt", int.class), "test", 1, 'e');
    15    }
    16 }
    

    运行此打印 true

    ----jGRASP exec:javac-g-Xlint:unchecked Sandbox.java

    找到:java.lang.Object
    要求:T
    1警告

    ----jGRASP:操作完成。

    最初,我在没有cast的情况下尝试了第8行,但是编译失败,出现了一个错误,抱怨找到了 Object 必要时 T ( invoke 返回 ). 后来,我就这样重写,一味希望摆脱警告。

    T actualReturn = method.getReturnType( ).cast(method.invoke(target, argument));
    

    但这就产生了一个编译错误,我无法完全理解。

    ----jGRASP exec:javac-g-Xlint:unchecked Sandbox.java


    要求:T

    --CheldPield:进程的退出代码是1。
    ----jGRASP:操作完成。

    旁边那个号码 capture#

    那么,到底是什么问题?为什么在将invoke返回的对象强制转换为类型变量时会收到警告?这是否表明我做错了什么?我该怎么写才能让警告消失呢?我不想用注释来抑制它,因为对我来说这似乎不是一个很好的解决方案。

    3 回复  |  直到 8 年前
        1
  •  5
  •   gdejohn    14 年前

    我进一步研究了这个问题,发现可以使用类文本作为运行时类型标记来解决这个问题,如 Java Tutorials .

    method.getReturnType( ).cast(...) ,但由于返回类型为 getReturnType( ) Class<?> Class<T>

    所以,现在的方法是这样的。

    public static <T> void foo(Class<T> returnType, Method method, String target, Object argument, T expectedReturn) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException
    {
        T actualReturn = returnType.cast(method.invoke(target, argument));
        System.out.print(actualReturn.equals(expectedReturn));
    }
    

    这是一个电话样本。

    foo(Character.class, String.class.getMethod("charAt", int.class), "test", 1, 'e');
    

    编译时没有警告和打印 true 到控制台。注意,如果您希望底层方法返回一个基元,那么returnType参数必须是其各自的包装类。

        2
  •  1
  •   thejh    15 年前

    T ? 你为什么不这样做呢?

    Object actualReturn = method.invoke(target, argument);
    System.out.print(actualReturn.equals(expectedReturn));
    

    哦,如果方法可以返回null和 expectedReturn 不是,这样更好:

    Object actualReturn = method.invoke(target, argument);
    System.out.print(expectedReturn.equals(actualReturn));
    
        3
  •  0
  •   Stan Kurilin    15 年前

    那么,到底是什么问题?为什么? 我投球的时候收到警告了吗 调用返回给

    方法可以返回任何对象。也不可能在所有情况下都是t。

    这是否表明我正在

    把反射和泛型混合起来是不好的做法,imho。

    我怎么能写这个让 警告消失了?

    我个人认为,如果不进行重构,就无法避免这一警告。

    推荐文章