Как вы решаете круговую зависимость с внутренним классом? - PullRequest
2 голосов
/ 23 сентября 2008

(вопрос по Java)

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

Как мне этого избежать?

Вот пример:

public class Outer {

  private Other o;
  private Inner i;    

  public Outer() {
    o = new Other();

    i = new Inner() {
      public void doSomething() {
        o.foo();
      }
    };

  }
}

Ответы [ 3 ]

10 голосов
/ 23 сентября 2008

Статический класс против экземпляра: Если вы объявляете внутренний класс как статический, то экземпляры внутреннего класса не имеют никакой ссылки на внешний класс. Если это не сатика, тогда ваш внутренний объект эффективно указывает на внешний объект, который его создал (фактически он имеет неявную ссылку, если вы используете отражение над его конструкторами, вы увидите дополнительный параметр для получения внешнего экземпляра). *

Внутренний экземпляр указывает на внешний экземпляр: Циркулярная ссылка на случай, если каждый экземпляр указывает на другой. Часто вы используете внутренние классы для элегантной реализации некоторого интерфейса и доступа к закрытым полям, не реализуя интерфейс с внешним классом. Это означает, что внутренний экземпляр указывает на внешний экземпляр, но не означает обратное. Не обязательно круговая ссылка.

Закрытие круга: В любом случае, нет ничего плохого в круговых ссылках в Java. Объекты работают хорошо, и когда на них больше нет ссылок, они собирают мусор. Не имеет значения, указывают ли они друг на друга.

0 голосов
/ 23 сентября 2008

(Не уверен, если это то, что вы спрашиваете ...)

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

0 голосов
/ 23 сентября 2008

Синтаксис, который вы используете в этом примере, немного отличается: здесь нет объявления класса или интерфейса Inner. Но в концепции примера нет ничего плохого. На Java это будет нормально работать.

Я не уверен, что вы здесь делаете, но вы можете рассмотреть более простой дизайн для удобства обслуживания и т. Д.

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

...