#java #reflection
#java #отражение
Вопрос:
Я пытаюсь получить значение из переменной класса с помощью отражения. Например, у меня есть Car
класс, и у него есть свойство engine. Кроме того, в Engine
классе я переопределил toString()
метод и определил еще один hello()
метод.
И затем, когда я пытаюсь получить значение с помощью
getDeclaredField()
метод, похоже, я получаю правильное значение Engine
экземпляра, но по некоторым причинам я не могу вызвать метод hello()
для него.
Класс Car
public class Car {
final Engine engine = new Engine();
}
Класс Engine
public class Engine {
public void hello() {
System.out.println("hello");
}
@Override
public String toString() {
return "Engine";
}
}
Основной класс
public class Main {
public static void main(String[] args) {
try {
Field field = Car.class.getDeclaredField("engine");
Object value = field.get(new Car());
// It's print Engine as expected
System.out.println(value);
// But I can't call hello() method
// value.hello()
} catch (NoSuchFieldException | IllegalAccessException e) {
System.out.println("Exception");
}
}
}
Ответ №1:
Чтобы вызвать hello()
метод, сначала убедитесь, что ваш value
является экземпляром Engine
(используя instanceof
), а затем приведите value
к Engine
. Нравится,
// Check type, cast instance and call hello() method
if (value instanceof Engine) {
((Engine) value).hello();
}
которые вы также можете написать как
if (value instanceof Engine) {
Engine.class.cast(value).hello();
}
также обычно сохранять Class
ссылку и использовать ее вместо жесткого кодирования конкретного объекта, с которым Class
вы работаете; например,
Class<? extends Engine> cls = Engine.class
// ...
if (cls.isAssignableFrom(value.getClass())) {
cls.cast(value).hello();
}
Комментарии:
1. Спасибо, Эллиотт! это работает как шарм! я думал, что когда мы получаем значение из свойства, оно уже имеет правильный тип и т.д.
Ответ №2:
Вам также необходимо вызвать
field.setAccessible(true);
прежде чем пытаться получить к нему доступ.
Хотя это может быть только для закрытых полей, см. @Elliott.Фриш отвечает
Комментарии:
1. Хм, это нужно только для
private
свойств, не так ли?