общедоступный анонимный внутренний класс в Java - PullRequest
0 голосов
/ 23 марта 2012

Являются ли анонимные внутренние классы закрытыми по умолчанию? Могу ли я сделать их публичными?

Мне нужно получить доступ к методам с помощью отражения.

Ответы [ 4 ]

7 голосов
/ 23 марта 2012

Анонимные внутренние классы являются анонимными по определенной причине: они не предназначены для прямого доступа из внешнего мира, только через ссылающуюся переменную / параметр метода. (И по той же причине они тоже являются частными.)

Полагаю, вы можете попытаться получить доступ к такому классу с помощью отражения, используя его имя, сгенерированное компилятором (например, OuterClass$1), однако это зависит от реализации и может измениться в момент добавления другого анонимного внутреннего класса к тому же внешнему классу или в следующей версии JVM. Поэтому такое решение было бы очень хрупким.

Почему вы на самом деле хотите это сделать? Если вы объясните свою настоящую проблему, мы сможем предложить лучшую альтернативу.

3 голосов
/ 23 марта 2012

Вы можете получить доступ к методам анонимного внутреннего класса с помощью отражения.См. 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, это будет невозможно, см. Каков риск безопасности отражения объекта?

Предупреждение: Примите во внимание, что анонимные внутренние классы являются своего рода одноразовыми определениями классов.После того, как вы их использовали, они вам больше никогда не понадобятся.Точно так же, как сказал @ PéterTörök, трудно сказать без контекста о вашей проблеме, но, если у вас есть контроль над этим классом, вероятно, было бы лучше деанонимировать этот класс (делая закрытый внутренний класс или даже публичный),и предоставьте этот метод нужным классам.

1 голос
/ 23 марта 2012

Анонимные внутренние классы имеют закрытый (по умолчанию) доступ к пакету. В Java 6 они являются окончательными, если они объявлены в статическом контексте, но не являются окончательными в других контекстах. (Я верю, но не проверял, что это изменилось в Java 7, так что они всегда являются окончательными; см. Раздел 15.9.5 Спецификации языка Java .)

Например, этот класс имеет четыре анонимных внутренних класса:

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) & mdash; пакет приватный
  • InnerTest$2 (foo2) & mdash; пакет приватный
  • InnerTest$3 (foo3) & mdash; пакет приватный и финальный
  • InnerTest$4 (foo4) & mdash; пакет приватный и финальный

Обратите внимание, что доступ к переменной, которой назначается экземпляр анонимного внутреннего класса, не имеет значения.

1 голос
/ 23 марта 2012

Анонимные внутренние классы являются закрытыми по умолчанию.Для использования с отражением вы можете посмотреть здесь - Отражение Java: Как я могу получить анонимные внутренние классы?

...