编辑: 我最初接受了 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/