3

I feel like this is a really basic question, but I've never got a situation like this. Right now I have a structure like this:

public class Main{
    ClassA a = new ClassA();
    ClassB b = new ClassB(a);
}

My ClassA is needed in ClassB as well as in the Main.class. Now I noticed that ClassA has to know ClassB as well.

public class Main{
    ClassA a = new ClassA(b);
    ClassB b = new ClassB(a);
}

Obviously won't work. First I thought of using a Observer Pattern but this seems to be an overkill to me, besides it's not what the pattern is usually used for.
Is there a way, that I can make Main.class know ClassA.class & ClassB.class, as well as make ClassA.class know ClassB.class and vice-versa? Since Main.class uses ClassA as well I have to have the same class only initialized once.

Peter
  • 1,844
  • 2
  • 31
  • 55
  • 1
    Its a circular dependency which you should avoid – Rahman Nov 25 '15 at 13:56
  • 1
    Why not assign it? Declare `b` first, then assign `a` to a variable in it. You don't necessarily have to put this in the constructor. – Arc676 Nov 25 '15 at 13:57
  • 1
    Like `Rehman` said, this is a guaranteed memory leak because the two objects will always point to each other, and unless one of them is explicitly set to `null`, neither will ever be garbage collected. – NRitH Nov 25 '15 at 13:58
  • 2
    There are a couple of solutions to this. You should tell us a bit more about your use case so we can find out what makes sense the most. – Cedric Reichenbach Nov 25 '15 at 13:59

4 Answers4

7

You don't need to set the references in the constructor. You can create a setter which you can call after you've created both objects such as b.setA(a);.

Kayaman
  • 72,141
  • 5
  • 83
  • 121
3

you can use a setter method

add to your ClassA:

public void setB(ClassB b) {
  this.b = b;
}

and then:

public class Main{
    ClassA a = new ClassA();
    ClassB b = new ClassB(a);
    a.setB(b);
}
Nir Levy
  • 12,750
  • 3
  • 21
  • 38
2

There's no way to create both a ClassA and a ClassB instance at once and pass them to each other's constructors.

What you could do is create a setter in ClassA to set the ClassB instance, which you call after creating both objects:

ClassA a = new ClassA();
ClassB b = new ClassB(a);
b.setA(a);

However, the fact that you need to have two objects which refer to each other is a red flag with regard to the design of the classes. It means that the two classes are very tightly coupled, and in general you want loose coupling.

It's better if you could change the design of your classes so that you don't need a circular dependency like this. Maybe you should just make them one class, or you could add an additional class that represents the link between the ClassA and ClassB objects - for example a ClassC that holds the references to the a and b objects.

Which solution is appropriate depends on what you're doing exactly; it's hard to tell without more information about your actual situation.

Jesper
  • 202,709
  • 46
  • 318
  • 350
0

You don't need the classes to know about each other but rather than a instance of ClassA to know about the b instance of ClassB.

In this case you could create a setter in ClassA and call it after the construction of b, or you can use magic. Some DI frameworks can implement said magic for you. One example of such masgic is to pass in a wrapper into the constructor of ClassA and set the wrapper to point to b post construction.

Finally you could look at your class structure. You currently have a circular dependency and they are generally bad things. Could ClassA and ClassB both be dependent on a new ClassC (which has no dependencies) for example?

Michael Lloyd Lee mlk
  • 14,561
  • 3
  • 44
  • 81