В Java, как я получаю доступ к внешнему классу, когда я не нахожусь во внутреннем классе?

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

arr = [
  [ 'A', 'A1', { "1" }],
  [ 'A', 'A2', { "2" }],
  [ 'B', 'B1', { "3" }],
]

matches = [sublist for sublist in arr if sublist[0] == 'B' and sublist[1] == 'B1']

for match in matches:
  print(match)
32
задан Kip 18 April 2009 в 14:43
поделиться

6 ответов

Байт-код класса Outer $ Inner будет содержать поле области пакета с именем это $ 0 типа Outer . Вот как в Java реализованы нестатические внутренние классы, потому что на уровне байт-кода нет понятия внутреннего класса.

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

Вот как будет выглядеть ваш пример кода при использовании отражения. Человек, это безобразно. ;)

public class Outer {
    public static void foo(Inner inner) {
        try {
            Field this$0 = inner.getClass().getDeclaredField("this$0");
            Outer outer = (Outer) this$0.get(inner);
            System.out.println("The outer class is: " + outer);

        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    public class Inner {
    }

    public void callFoo() {
        // The constructor of Inner must be called in 
        // non-static context, inside Outer.
        foo(new Inner()); 
    }

    public static void main(String[] args) {
        new Outer().callFoo();
    }
}
32
ответ дан 27 November 2019 в 20:31
поделиться

Что плохого в добавлении геттера, когда вам нужен доступ к внешнему классу? Таким образом, вы можете контролировать, разрешен ли доступ или нет.

8
ответ дан 27 November 2019 в 20:31
поделиться

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

14
ответ дан 27 November 2019 в 20:31
поделиться

Разве вы не можете просто сделать что-то вроде этого:

public static class Inner { // static now
    private final Outer parent;

    public Inner(Outer parent) { this.parent = parent; }

    public Outer get Outer() { return parent; }
}
0
ответ дан 27 November 2019 в 20:31
поделиться

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

Например:

public class Outer{ 
   public class Inner {
   }
}

public class UsesInner{
 Collection<Outer.Inner> c = new ArrayList<Outer.Inner>();
}

Теперь единственный способ заполнить c - это создать экземпляры Outer (). Мне было бы любопытно увидеть полезную цель для чего-то подобного.

1
ответ дан 27 November 2019 в 20:31
поделиться

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

Для записи «внутренний. getClass (). getDeclaredField ("этот $ 0") "работает. Поскольку поле является частным, вам также необходимо вызвать field.setAccessible (true).

1
ответ дан 27 November 2019 в 20:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: