Редактировать: Первоначально я принял ответ thejh, но меня это не очень устраивало, поскольку я хотел правильно использовать дженерики.Итак, я продолжил исследования и нашел решение.Читайте об этом в моем ответе ниже.
Вот небольшой фрагмент кода 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: не проверено Sandbox.java
Sandbox.java:8: предупреждение: [не проверено] не проверено приведение
найдено: java.lang.Object
обязательно: T
1предупреждение
---- jGRASP: операция завершена.
Первоначально я пробовал строку 8 без приведения, но не удалось скомпилировать с ошибкой, сообщающей об обнаружении Object
когда требуется T
(invoke
возвращает Object
).Позже я переписал это так, слепо надеясь избавиться от предупреждения.
T actualReturn = method.getReturnType( ).cast(method.invoke(target, argument));
Но это дает ошибку компиляции, которую я не могу сделать ни головой, ни хвостом.
---- jGRASP exec: javac -g -Xlint: не проверено Sandbox.java
Sandbox.java:8: несовместимые типы
найдено: захват # 898 из?
требуется: T
1 ошибка
---- клин jGRASP: код завершения процесса равен 1.
---- jGRASP: операция завершена.
И это число рядом с capture#
отличается каждый раз, когда я пытаюсь скомпилировать с одной и той же строкой кода.
Итак, в чем именно проблема?Почему я получаю предупреждение, когда я приведу объект, возвращаемый invoke, к переменной типа?Означает ли это, что я делаю что-то не так?Как я могу написать это, чтобы предупреждение исчезло?И я предпочел бы не подавлять это аннотацией, поскольку это не кажется мне большим решением.