Задача
Один друг предложил интересную проблему. Учитывая следующий код:
public class OuterClass {
private String message = "Hello World";
private class InnerClass {
private String getMessage() {
return message;
}
}
}
Из внешнего класса, как мне распечатать содержимое переменной message
? Конечно, изменение доступности методов или полей не разрешено.
(источник здесь , но это французский блог)
<Ч />
Решение
Код для решения этой проблемы следующий:
try {
Method m = OuterClass.class.getDeclaredMethod("access$000", OuterClass.class);
OuterClass outerClass = new OuterClass();
System.out.println(m.invoke(outerClass, outerClass));
} catch (Exception e) {
e.printStackTrace();
}
Обратите внимание, что имя метода access$000
на самом деле не является стандартным (даже если этот формат настоятельно рекомендуется ), и некоторые JVM будут называть этот метод access$0
. Таким образом, лучшим решением является проверка синтетических методов:
Method method = null;
int i = 0;
while ((method == null) && (i < OuterClass.class.getDeclaredMethods().length)) {
if (OuterClass.class.getDeclaredMethods()[i].isSynthetic()) {
method = OuterClass.class.getDeclaredMethods()[i];
}
i++;
}
if (method != null) {
try {
System.out.println(method.invoke(null, new OuterClass()));
} catch (Exception e) {
e.printStackTrace();
}
}
<Ч />
Итак, интересным моментом в этой проблеме является выделение использования синтетических методов. С помощью этих методов я могу получить доступ к закрытому полю, как это было сделано в решении. Конечно, мне нужно использовать рефлексию, и я думаю, что использование такого рода вещей может быть довольно опасным ...
Вопрос
Каков интерес - для меня, как разработчика, - к синтетическому методу? Какая может быть хорошая ситуация, когда использование синтетики может быть полезным?