2014-01-19 2 views
1
class A { 
    B ob1 = new B(); 
} 

class B { 
    A ob2 = new A(); 
} 

class C { 
    A a = new A(); 
    // I am getting a StackOverflowException here 
} 

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

+10

Java должен Javascript, как автомобиль на ковер. – SLaks

+0

Какая часть ошибки вы не понимаете? Как вы думаете, что делает ваш код? – SLaks

+5

'A' создает новый' B', который создает новый 'A', который создает новый' B', который создает новый 'A', который создает новый' B', который создает новый 'A', который создает новый' B', который создает новый 'A', который создает новый' B', который создает новый 'A', который создает новый' B', который создает новый 'A', который создает новый' B', который создает новый 'A 'который создает новый' B', который создает новый 'A', который создает новый' B', который создает новый 'A', который создает новый' B', который создает новый 'A', который создает новый' B' который создает новый 'A', который создает новый' B', который создает новый 'A', который создает новый ... –

ответ

3

Если вы хотите, чтобы объект B держать ссылку на объект, который создал его, вы хотите что-то вроде этого:

class A { 
    B ob1 = new B(this); 
} 

class B { 
    A a; 

    public B(A a) { 
     this.a = a; 
    } 

} 

Это не приведет к StackOverflow и B будет знать о А и А будет знать о B. Что вы делали, это создать экземпляр A, который создал экземпляр B, который создал экземпляр A, который создал ...

+0

Это предложение утечки 'this' в конструкторе. Это очень плохая практика. Единственный способ разрешить это - статический заводский метод. –

+0

Я согласен и понимаю это. Во многих простых случаях это не проблема? Тем не менее, я обновлю свой ответ позже, спасибо. –

7

Проблема с вашим подходом заключается в том, что при создании экземпляра A это экземпляр должен создать экземпляр B, который также должен создать экземпляр A, который создает экземпляр B ... и так далее, пока стек не переполнится.


Вероятно, наиболее интуитивный способ бы решить эту проблему с помощью геттеров/сеттеры, как

class A{ 
    private B b; 
    public void setB(B b) { this.b = b; } 
    public B getB() { return b; } 
} 

class B{ 
    private A a; 
    public void setA(A a) { this.a = a; } 
    public A getA() { return a; } 
} 

class Demo { 
    public static void main(final String[] args) throws Exception { 
     A a = new A(); 
     B b = new B(); 
     //let them see each other 
     a.setB(b); 
     b.setA(a); 
    } 
} 
+0

Согласен: предварительно создайте объекты и соедините их позже. Нет никаких шансов получить круговые ссылки. –

+0

Это, безусловно, действительный подход и решает проблему. Я бы предпочел фабричный шаблон, чтобы инкапсулировать связь, но это, вероятно, только я, параноик. –

+1

@BoristheSpider Я старался избегать излишних вещей, но не стесняйтесь публиковать ответ на основе заводского шаблона. Вы получите мой +1. – Pshemo

Смежные вопросы