Java Reflection: работа с приватными полями и методами
Используя механизм рефлексии в Java, клиент получает широкие возможности как для извлечения значений из инкапсулированных полей класса, так и для получения значений, возвращаемых инкапсулированными методами класса.
Работа с приватными полями
Для получения доступа к приватным полям класса, прежде всего необходимо получить экземпляр класса java.lang.reflect.Field. Для этого нужно воспользоваться Class.getDeclaredField(String name) либо Class.getDeclaredFields() методами класса Class. Обратите внимание на то, что методы Сlass.getField(String name) и Class.getFields() предоставляют доступ только к полям, объявленных с модификатором доступа public. Из этого следует, что они не предоставляют возможности для получения полей, объявленных с модификаторами доступа protected и private.
Рассмотрим более детально доступ к приватным полям класса на примерах, приведённых в Листингах 1 и 2.
Листинг 1. Класс PrivateObject
public class PrivateObject {
private String privateString = null;
public PrivateObject(String privateString) {
this.privateString = privateString;
}
}
Листинг 2. Реализация доступа к приватному полю класса PrivateObject
PrivateObject privateObject = new PrivateObject("The Private Value");
Field privateStringField = PrivateObject.class.getDeclaredField("privateString");
privateStringField.setAccessible(true);
String fieldValue = (String) privateStringField.get(privateObject);
System.out.println("fieldValue = " + fieldValue);
При выполнении кода, приведённого в Листинге 2, на экран будет выведено сообщение “fieldValue = The Private Value”, содержащее значение приватного поля privateString класса PrivateObject. Обратите внимание на использование метода PrivateObject.class.getDeclaredField(“privateString”). Этот метод возвращает поле именно того класса, у которого непосредственно вызывается метод getDeclaredField(String name). Другими словами, этот метод не предоставляет доступ к полям, объявленных в суперклассах. Далее, вызывая метод setAccessible(true) у экземпляра privateStringField класса Field, вы тем самым предоставляете механизму рефлексии доступ к приватному полю privateString объекта privateStringField.
Работа с приватными методами
Для получения доступа к приватным методам класса, прежде всего необходимо получить экземпляр класса java.lang.reflect.Method. Для этого нужно воспользоваться Class.getDeclaredMethod(String name, Class[] parameterTypes) либо Class.getDeclaredMethods() методами класса Class. Заметьте, что методы Сlass.getMethod(String name) и Class.getMethods() предоставляют доступ только к методам, объявленных с модификатором доступа public. Из этого следует, что они не предоставляют возможности для получения методов, объявленных с модификаторами доступа protected и private.
Рассмотрим более детально доступ к приватным методам класса на примерах, приведённых в Листингах 3 и 4.
Листинг 3. Класс PrivateObject с приватным методом getPrivateString()
public class PrivateObject {
private String privateString = null;
public PrivateObject(String privateString) {
this.privateString = privateString;
}
private String getPrivateString(){
return this.privateString;
}
}
Листинг 4. Реализация доступа к приватному методу класса PrivateObject
PrivateObject privateObject = new PrivateObject("The Private Value");
Method privateStringMethod = PrivateObject.class.getDeclaredMethod("getPrivateString", null);
privateStringMethod.setAccessible(true);
String returnValue = (String)
privateStringMethod.invoke(privateObject, null);
System.out.println("returnValue = " + returnValue);
При выполнении кода, приведённого в Листинге 4, на экран будет выведено сообщение “returnValue = The Private Value”. Данное сообщение содержит значение “The Private Value”, возвращаемое методом getPrivateString(). Обратите внимание на использование метода PrivateObject.class.getDeclaredMethod(“getPrivateString”, null). Этот метод возвращает метод именно того класса, у которого непосредственно вызывается метод getDeclaredMethod(String name, Class[] parameterTypes). Другими словами, этот метод не предоставляет доступ к методам, объявленных в суперклассах. Далее, вызывая метод setAccessible(true) у экземпляра privateStringMethod класса Method, вы тем самым предоставляете механизму рефлексии доступ к приватному методу getPrivateString() объекта privateStringField.
Источник: http://tutorials.jenkov.com/
Тэги: field, Java, method, reflection


