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();
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.
What actually happens is that you create an instance of Class1
in the constructor,
Class2
in the constructor,
Class1
in the constructor,
Class2
in the constructor,
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.
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.