Java classes reference each other

前端 未结 3 970
执笔经年
执笔经年 2021-01-17 22:18

I have two java class files. Each of them has methods the other one uses.

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


        
相关标签:
3条回答
  • 2021-01-17 22:55

    Is there some way to have the classes refer to each other or do I have no choice but to transfer all of my methods into a single class?

    In my opinion, cyclic references are a code-smell. See this answer for an explanation. Take special note of the point about cognitive load.

    The solution is to have one class depend on the other and delegate the calls to the other class :

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

    This way, you are not really transferring all the methods to one class but just composing class2 into class1. Other classes that were depending on class1 and class2 only have to depend on class1 instead.

    0 讨论(0)
  • 2021-01-17 22:57

    What actually happens is that you create an instance of Class1 in the constructor,

    • which creates an instance of Class2 in the constructor,
      • which creates an instance of Class1 in the constructor,
        • which creates an instance of Class2 in the constructor,
          • et cetera.

    Your constructors are recursingly creating instances, causing the call stack to flood, resulting in a StackOverflowError.

    I assume you want an instance of Class1 to hold a reference to an instance of Class2 and vice versa?

    In that case, you can just do this:

    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;
        }
    }
    

    Cyclic aggregations like this are often a sign of a bad design; but there are situations where it is perfectly valid, or at least reflects reality.

    0 讨论(0)
  • 2021-01-17 23:01

    As is said above, this is a sign of code smell.

    Having a setter to set the method afterwards is not satisfactory, as you have an object in an indeterminate state, until the setters are called.

    Although using a dependency framework such as Spring can help solve the above problem, if you use constructor injection, then you cannot have cyclic dependencies either! But at least when a bean is injected, you are sure it is not half constructed.

    If you don't want to use a dependency injection framework, consider a factory pattern where both objects are created by a factory method, which returns a tuple (or a container object in the case of Java which has no native support for tuples) containing the fully constructed objects.

    0 讨论(0)
提交回复
热议问题