Являются ли анонимные внутренние классы частными по умолчанию? Могу ли я сделать их общедоступными?общедоступный анонимный внутренний класс в Java
Мне нужно получить доступ к методам отражения.
Являются ли анонимные внутренние классы частными по умолчанию? Могу ли я сделать их общедоступными?общедоступный анонимный внутренний класс в Java
Мне нужно получить доступ к методам отражения.
Вы можете использовать методы анонимного внутреннего класса с отражением. См. getDeclaredMethods()
. Не забудьте позвонить в setAccessible(true)
на номер Method
, чтобы избежать IllegalAccessException
.
Object testObject = new Object() {
private void testMe() {
System.out.println("testme");
}
};
Method m = testObject.getClass().getDeclaredMethod("testMe");
m.setAccessible(true);
m.invoke(testObject); // prints out "testme"
заметить также, что если есть SecurityManager
это не будет возможным, см What is the security risk of object reflection?
Предупреждения: Примите во внимание, что анонимные внутренние классы являются своим родом одноразовых определений класса. После использования вам больше никогда не понадобится их в другом месте. Точно так же, как @ PéterTörök сказал, трудно сказать без лишнего контекста вашей проблемы, но, если у вас есть контроль над этим классом, вероятно, было бы лучше деанонизировать этот класс (создание частного внутреннего класса или даже публичного) и разоблачить этот метод для классов, которые в нем нуждаются.
Анонимные внутренние классы анонимны по причине: они не предназначены для доступа непосредственно из внешнего мира, только через ссылочный параметр variable/method. (И по той же причине, что они являются частными тоже.)
Я думаю, вы могут попытаться получить доступ к такому классу с помощью отражения, используя его компилятор генерируется имя (например, OuterClass$1
), однако это зависит от конкретной реализации и может изменяться когда вы добавите другой анонимный внутренний класс в тот же внешний класс или в следующую версию JVM. Поэтому такое решение было бы очень хрупким.
Почему вы на самом деле хотите это сделать? Если вы объясните свою фактическую проблему, мы сможем предложить лучшую альтернативу.
Я не согласен. Единственная разница между не анонимными и анонимными внутренними классами заключается в том, что у последних нет имени. Причиной этого является краткость, а не безопасность. Поэтому причина анонимных классов не может быть общедоступной, так как синтаксис не был предложен. ИМХО. – Dims
+1 Не нужно использовать имя класса, сгенерированное компилятором, если у вас есть экземпляр (хотя это присуще анонимному внутреннему классу). –
@ XaviLópez, действительно. Если у вас есть экземпляр, зачем вам размышлять? –
Анонимные внутренние классы по умолчанию являются закрытыми. Для использования с рефлексами вы можете посмотреть здесь - Java reflection: How can I retrieve anonymous inner classes?
У анонимных внутренних классов есть доступ по умолчанию (закрытый пакет), а не частный. –
моя ошибка спасибо за исправление – aretai
Анонимные внутренние классы имеют доступ к частному (по умолчанию). В Java 6 они являются окончательными, если объявлены в статическом контексте, но не окончательны в других контекстах. (Я считаю, но не проверял, что это изменилось в Java 7, так что они всегда окончательным; см Section 15.9.5 of the Java Language Specification.)
Например, этот класс имеет четыре анонимных внутренних классов:
public class InnerTest {
public Runnable foo1 = new Runnable() {
public void run() {foo1();}
void foo1() {}
};
private Runnable foo2 = new Runnable() {
public void run() {foo2();}
void foo2() {}
};
public static Runnable foo3 = new Runnable() {
public void run() {foo3();}
void foo3() {}
};
private static Runnable foo4 = new Runnable() {
public void run() {foo4();}
void foo4() {}
};
}
Когда скомпилированный с javac (версия 1.6.0_26), он генерирует четыре анонимных внутренних класса.Декомпиляция с javap -c
показывает:
InnerTest$1
(foo1
) — пакет частныхInnerTest$2
(foo2
) — пакет частныхInnerTest$3
(foo3
) — пакет приватным и окончательныйInnerTest$4
(foo4
) — пакета приватное и окончательныйОбратите внимание, что доступ к переменному, к которой анонимный экземпляру внутреннего класса быть назначен не имеет значения.
Если это анонимный внутренний класс, как компилятор знал бы, где искать эти методы? Почему вы не просто создаете публичный класс и используете его в тех местах, где вам нужно, а не для использования анонимного класса? – jzworkman