Доступ к внутренним анонимным членам класса

Есть ли другой способ, кроме использования отражения, для доступа к членам анонимного внутреннего класса?

Могу я спросить, зачем вам это нужно? Некоторый контекст .. Не уверен, что это хорошая идея, даже если это возможно.

Gishu 26.11.2008 07:52

У меня нет конкретного варианта использования. Просто хотел знать, есть ли какой-либо другой механизм, кроме отражения, для запроса / доступа к членам объекта.

Saravanan M 26.11.2008 16:06
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
6
2
8 935
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

Если он реализует интерфейс или расширяет существующий класс, вы можете получить доступ к членам, определенным в интерфейсе или базовом классе.

Мистер Фуз прав, за исключением того, что интерфейсы могут определять только постоянные члены. лучший способ - добавить в интерфейс методы получения и установки, а затем использовать их для получения значения. но тогда для каждого анонимного класса вам нужно будет определить эти методы (что-то вроде боли).

Метод являются членами своих типов, как и поля.

erickson 26.11.2008 10:47

Вы можете использовать локальные классы вместо анонимного класса. Смотреть:

public class Test {
    public static void main(String... args) {
        class MyInner {
            private int value = 10;
        }

        MyInner inner = new MyInner();
        System.out.println(inner.value);
    }
}

Однако вы можете иметь ссылку на тип MyInner только в теле метода. Таким образом, вне метода вы не сможете использовать его поля / методы, которые не объявлены в его суперклассе (в данном случае java.lang.Object) или интерфейсе.

Вау ... никогда не видел их раньше. Странно. Не могу сказать, что мне это очень нравится, но тем не менее интересно :)

Jon Skeet 26.11.2008 10:26

Их называют местными классами.

Tom Hawtin - tackline 26.11.2008 14:35

Если я не ошибаюсь, показанный вами класс - это просто еще один класс с ограниченной видимостью ... верно? Я имел в виду вопрос о возможном доступе к членам анонимного объекта класса.

Saravanan M 26.11.2008 16:10

public class AccessAnonymous {
    private Runnable runnable; // to have instance of the class

    public static void main(String[] args) throws Exception {
        AccessAnonymous a = new AccessAnonymous();
        a.a(); // init field

        Class clazz = a.runnable.getClass();
        Field field = clazz.getDeclaredField("i");
        field.setAccessible(true);

        int int1 = field.getInt(a.runnable);
        System.out.println("int1 = " + int1);
    }

    public void a() {
        runnable = new Runnable() {
            private int i = 1;

            public void run() {
                i = 90;
            }

        };
        runnable.run();// change value
    }
}
Ответ принят как подходящий

Анонимные внутренние классы имеют тип, но не имеют имени.

Вы можете получить доступ к полям, не определенным названным супертипом. Однако после присвоения переменной именованного типа интерфейс теряется.

Очевидно, вы можете получить доступ к полям из самого внутреннего класса. Один из способов добавления кода - инициализатор экземпляра:

final AtomicInteger y = new AtomicInteger();
new Runnable() {
    int x;
    {
        x = 5;
        doRun(this);
        y.set(x);
    }
    public void run() {
        ... blah ...
    }
};

Значение, возвращаемое выражением анонимного внутреннего класса, имеет анонимный тип, поэтому у вас есть один шанс использовать его вне самого класса:

final int y = new Runnable() {
    int x;
    {
        x = 5;
        doRun(this);
    }
    public void run() {
        ... blah ...
    }
}.x;

Вы также можете передать его через метод, объявленный аналогично:

<T extends Runnable> T doRun(T runnable);

Если вам нужен читаемый, поддерживаемый код, не используйте анонимные классы. Если вы используете анонимные классы и хотите читать и поддерживать код, не используйте анонимные классы, когда вам нужно получить доступ к элементу в этом внутреннем классе. Есть способы сделать это, но я прошу вас не использовать ни один из этих приемов. Читаемость превосходит все другие достоинства.

В случае анонимных классов также существует компромисс между беспорядком, вызываемым классом, и удобством его анонимности. Сложные классы редко принадлежат к анонимным, а скорее относятся к именованным частным внутренним.

В большинстве анонимных классов нам нужно только «кормить» знаниями, и мы можем делать это при построении. В некоторых анонимных классах (например, в транспортных средствах с возвращаемым значением) мы также заботимся об одном возвращаемом значении.

Как мы знаем, к элементам данных следует обращаться не напрямую, а с помощью установщика геттера. Таким образом, если вы оказались в ситуации, когда вы добавили много геттеров и сеттеров, вы, вероятно, все равно делаете что-то не так и не должны использовать анонимный класс.

Другие вопросы по теме