Могу ли я получить доступ к внешнему классу из статического внутреннего класса?

У меня есть класс, у которого есть другой static внутренний класс:

class A {
    private List<String> list;

    public static class B {
        // I want to update list here without making list as static 
        // I don't have an object for outer class
    }
}

Ответы

Ответ 1

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

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

public class A {
    private List<String> list = new ArrayList<String>();
    public List<String> getList() {
        return list;
    }
    public void setList(List<String> list) {
        this.list = list;
    }
    public static class B {
        // i want to update list here without making list as static
        void updList() {
            A a = new A();
            a.setList(someOtherList);
            System.out.println(a.getList());
        }
    }
} 

Ответ 2

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

Ответ 3

Нет, для этого вам понадобится внутренний класс < static.

Из JLS §8.5.1:

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

Это ошибка времени компиляции, если класс static содержит использование нестатического элемента охватывающего класса.

Ответ 4

В вашем коде list является переменной экземпляра класса A и B является вложенным статическим классом. Правила доступа к статическому и не статическому члену не изменяются для вложенного статического класса.

  • Переменная list - это переменная экземпляра, поэтому доступ из статического контекста невозможен.
  • Чтобы включить это, вам необходимо изменить класс статического nester на внутренний класс.

    class A {
    private List<String> list = new ArrayList<String>();
      public class B {
         public void someMethod(){
             list.add("abc");
         }
      }
    }
    

Ответ 5

private List<String> list;

Здесь list - это переменная экземпляра, в то время как внутренний класс является статическим, что означает, что класс B одинаковый для разных экземпляров класса A; к нему нельзя получить доступ. И это тоже по очень хорошей и очевидной причине.

Одним из решений, которое вы можете использовать, является ссылка на ссылку члена list на конструктор класса B с weakReference, чтобы избежать утечки памяти.

Что-то вроде этого:

class A {
    private List<String> list;

    public static class B {
        WeakReference<List<String>> innerList;
        //constructor
        B(WeakReference<List<String>> innerList){
            this.innerList = innerList;
        }
    }