Java: можно иметь взаимные, окончательные ссылки на классы? - PullRequest
7 голосов
/ 21 августа 2009

Допустим, у меня есть два класса, названных A и B, которые связаны друг с другом, так что наиболее удобно, если объект каждого класса содержит ссылку на другой. Другими словами, класс A имеет переменную "b" класса B. В классе B есть переменная "a" класса A. Таким образом, код в каждом классе имеет легкий доступ к другому классу.

Есть ли способ настроить эту ассоциацию на "окончательную"? переменная b в классе A является конечной, а переменная a в классе B конечной? Похоже, что установка этих ссылок в конструкторе (как этого требует ключевое слово final) требует нелогичной циклической ссылки.

Это скорее концептуальный вопрос, чем практический. Спасибо!

Ответы [ 3 ]

6 голосов
/ 21 августа 2009

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

public class A {
    final B b;
    public A() {
        b = new B(this);
    }
    public B getB() {
        return b;
    }
}
public class B {
    final A a;
    public B(A a) {
        this.a = a;
    }
}
6 голосов
/ 21 августа 2009

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

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

Дополнительные потенциальные проблемы возникают, если учесть, что конструктор второго класса не может ссылаться на неинициализированные члены первого класса.

Мое предложение заключается в том, что если два класса настолько взаимосвязаны, что вы хотите, чтобы у каждого из них были окончательные ссылки на другой, просто делает их одним и тем же классом . Тогда у вас всегда есть окончательная ссылка на другой объект: this.

1 голос
/ 21 августа 2009

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

объявляет зависимости a-b и b-a и вставляет одну из них в другой класс. guice сделает немного магии, чтобы оба поля были финальными. в основном он сначала внедрит один прокси, а затем установит свой делегатор.

вам нужен пример кода для этого?

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