Вы можете установить приватную переменную другого объекта через отражение.Вот пример того, как это сделать.Рассмотрим следующий объект с закрытой переменной:
public class MyBean {
private String message;
}
Обычно поле message обычно не доступно извне MyBean , однако SnoopyClass можно установить и получить его значение.Я написал два статических метода: setValue
, который может установить значение в закрытое поле с именем fieldName объекта bean и метод getValue
, который можетполучить значение закрытой переменной fieldName из объекта bean .
Метод main просто демонстрирует его использование путем создания объектаКласс MyBean, установка переменной message и ее получение.Я на самом деле тестировал этот код как отдельное приложение, и оно работает.
import java.lang.reflect.Field;
public class SnoopyClass {
private static void setValue(Object bean, String fieldName, Object value)
throws IllegalArgumentException, IllegalAccessException,
SecurityException, NoSuchFieldException {
Field privateVar = bean.getClass().getDeclaredField(fieldName);
privateVar.setAccessible(true);
privateVar.set(bean, value);
}
private static Object getValue(Object bean, String fieldName)
throws IllegalArgumentException, IllegalAccessException,
SecurityException, NoSuchFieldException {
Field privateVar = bean.getClass().getDeclaredField(fieldName);
privateVar.setAccessible(true);
return privateVar.get(bean);
}
public static void main(String[] argv)
throws IllegalArgumentException, SecurityException,
IllegalAccessException, NoSuchFieldException {
MyBean instance = new MyBean();
setValue(instance, "message", "Shht! Don't tell anyone!");
System.out.println("The message is '" + getValue(instance, "message"));
}
}
Реализация использует метод getDeclaredField
в классе Object, потому что этот метод может искать все поля, даже частные.Напротив, getField
может получить доступ только к публичным участникам.Следующим шагом является вызов setAccessible
в поле, чтобы разрешить его чтение и запись.Последний шаг - это просто использование методов get
и set
, предоставляемых классом java.lang.reflect.Field
.
Этот вид манипуляции разрешен только в том случае, если менеджер безопасности позволяет это.По умолчанию Java не устанавливает никакого менеджера безопасности, поэтому в автономной программе, которую вы запускаете через IDE или командную строку, у вас не возникнет проблем с использованием этой техники.Я также пробовал в приложении Spring под Tomcat, и оно все еще работает.
Основное приложение, по крайней мере для меня, может устанавливать частные переменные в моих модульных тестах, особенно для Spring Beans,без загрязнения интерфейса ненужными установщиками.