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

标签 java generics reflection casting

编辑: 我最初接受了 thejh 的回答,但我对它不是很满意,因为我想正确使用泛型。所以,我一直在研究并找到了解决方案。在 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 打印到控制台,这是我所期望的。困扰我的是,由于第 8 行的转换,我在编译它时收到如下警告(顺便说一下,jGRASP 是我的 IDE)。

----jGRASP exec: javac -g -Xlint:unchecked Sandbox.java
Sandbox.java:8: warning: [unchecked] unchecked cast
found : java.lang.Object
required: T
1 warning

----jGRASP: operation complete.

最初,我在没有转换的情况下尝试了第 8 行,但是编译失败并出现错误,提示在需要 T 时找到 Object (invoke 返回一个 Object)。后来就这样重写了,一味的希望去掉warning。

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

但这给出了一个编译错误,我无法弄清楚。

----jGRASP exec: javac -g -Xlint:unchecked Sandbox.java
Sandbox.java:8: incompatible types
found : capture#898 of ?
required: T
1 error

----jGRASP wedge: exit code for process is 1.
----jGRASP: operation complete.

每次我尝试使用同一行代码进行编译时,capture# 旁边的数字都不同。

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

最佳答案

我进一步研究了这个问题,发现我可以通过使用类文字作为运行时类型标记来解决这个问题,如 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 参数需要是其各自的包装类。

关于java - 在 Java 中转换为泛型方法类型变量时出现编译器警告,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4117500/

相关文章:

java - 如何使用 FasterXML 获取 JSON 字段出现的所有位置的完整路径?

java - 参数化方法类型在列表中不起作用

java - Max element - Sun 的答案 VS 我的

reflection - 如何使用 Kotlin 反射更改成员字段?

java - IntelliJ IDEA 9 CE "Create New Class"对话框 UI 元素用途

java - 如何用 Java 打印 tar.gz 文件的内容?

java - 使用 Dagger 注入(inject)通配符类型

c# - 是否可以在使用嵌套的 Elasticsearch 中定义通用索引?

c# - 当属性类型未知时,为通过反射获得的属性评估器创建委托(delegate)

python - 使用locate动态实例化类