2015-06-28 3 views
8

У меня есть два файла класса java. Каждый из них имеет методы, которые использует другой.Классы Java ссылаются друг на друга

public class class1{ 
    class2 c2 = new class2(); 
    m1(){ 
     c2.ma(); 
     m2(); 
    } 
    m2(){} 
} 

public class class2{ 
    class1 c1 = new class1(); 
    ma(){} 
    mb(){ 
     c1.m2(); 
    } 
} 

Линии

class1 c1 = new class1(); 

и

class2 c2 = new class2(); 

ссылаются друг на друга вызывает бесконечный цикл, что приводит к ошибке java.lang.StackOverflowError.

Есть ли способ, чтобы классы относились друг к другу или у меня нет выбора, кроме как передать все мои методы в один класс?

+1

Это какая-то практика? Если нет, циклические ссылки, вероятно, могут быть запахом кода. Вам действительно нужны оба класса, чтобы зависеть друг от друга? – CKing

+0

Проверьте этот шаблон: https://en.wikipedia.org/wiki/Inversion_of_control –

+0

Переполнение стека не имеет ничего общего с классами, ссылающимися друг на друга. Это вполне возможно и поддерживается Java для этого. Исключение вызвано слишком глубоким recursin, это может произойти и с одним методом/классом. – eckes

ответ

1

Есть ли способ, чтобы классы относились друг к другу или у меня есть нет выбора, кроме как передать все мои методы в один класс?

На мой взгляд, циклические ссылки являются кодовым запахом. См. this ответ на объяснение. Особо следует отметить пункт о cognitive load.

Решение состоит в том, чтобы иметь один класс зависит от другого и делегировать вызовы к другому классу:

public class class1{ 
    class2 c2 = new class2(); 
    m1(){ 
     c2.ma(); 
     m2(); 
    } 
    m2(){} 
} 

public class class2{ 
    ma(){} 
} 

Таким образом, вы на самом деле не передавая все методы в одном классе, но только сочинял class2 в class1. Другие классы, зависящие от class1 и class2, должны зависеть только от class1.

+0

Может ли downvoter, пожалуйста, сообщить мне, что не так с моим ответом? Может ли downvoter понять «Java»? – CKing

6

Как сказано выше, это признак запаха кода.

Наличие установки для установки метода впоследствии неудовлетворительно, так как у вас есть объект в неопределенном состоянии, пока вызывающие устройства не будут вызваны.

Хотя использование структуры зависимостей, такой как Spring, может помочь решить вышеупомянутую проблему, если вы используете инъекцию конструктора, то вы также не можете иметь циклические зависимости! Но, по крайней мере, когда вы вводите фасоль, вы уверены, что она не построена наполовину.

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

+0

Отличный ответ. 1+. Я удаляю свой ответ в пользу этого. –

+0

@HovercraftFullOfEels Просто агрегация наших ответов. :) – CKing

+3

@ChetanKinger: возможно, но и ваши ответы лучше моих. У меня больше голосов за то, что они были первыми, но это неправильно. –

0

Что на самом деле происходит то, что вы создаете экземпляр Class1 в конструкторе,

  • , который создает экземпляр Class2 в конструкторе,
    • , который создает экземпляр Class1 в конструкторе,
      • , который создает экземпляр Class2 в конструкторе,
        • et cetera.

Ваши конструкторы recursingly создания экземпляров, вызывая стек вызовов затопить, в результате чего StackOverflowError.

Предполагаете, вы хотите, чтобы экземпляр Class1 содержал ссылку на экземпляр Class2 и наоборот?

В этом случае, вы можете просто сделать это:

public class Class1 { 

    private Class2 c2; 

    public Class1() { 
     this.c2 = new Class2(this); 
    } 
} 

public class Class2 { 

    private Class1 c1; 

    public Class2(Class1 class1) { 
     this.c1 = class1; 
    } 
} 

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

+0

@HovercraftFullOfEels Держу пари, что вы не видели этого :) :) – CKing

+0

StackOverflow hah! –

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