Reputation: 8923
public class Graph {
private Node node;
public void createGraph()
{
}
private class Node<K>{
K data;
List<Node> adjacent;
boolean visited;
Node()
{
adjacent = new ArrayList<Node>();
visited = false;
}
Node(K data)
{
this.data = data;
this.Node();
}
}
}
Why is the compiler complaining that I can't call this.Node() ?
Upvotes: 1
Views: 2652
Reputation: 15230
Try:
Node(K data)
{
this();
this.data = data;
}
The call to the "other" constructor needs to be always first. The call to the other constructors from inside a constructor is always done with this(...)
not with Node(...)
.
JLS section 8.8.7 specify how the constructor body should look like:
ConstructorBody: { ExplicitConstructorInvocation(opt) BlockStatements(opt) }
where ExplicitConstructorInvocation(opt)
is either an alternate constructor or a constructor from the parent class invoked with super(...)
.
and JLS section 12.5 specify the object initialization steps when a constructor is called:
Just before a reference to the newly created object is returned as the result, the indicated constructor is processed to initialize the new object using the following procedure:
Assign the arguments for the constructor to newly created parameter variables for this constructor invocation.
If this constructor begins with an explicit constructor invocation (§8.8.7.1) of another constructor in the same class (using this), then evaluate the arguments and process that constructor invocation recursively using these same five steps.
...
These JLS rules make sure that the parent class constructor is called first and once.
Upvotes: 8
Reputation: 887275
You can only ever call another constructor as the first statement in the current constructor.
Move this.data = data;
below this()
.
Upvotes: 6
Reputation: 13807
When i need to create more constructors, i do it this way (assuming, the set of parameters would only expand, and not change entirely):
public class Foo
{
private static final int DEFAULT_SECOND = ...;
private static final int DEFAULT_FIRST = ...;
//Constructor with the biggest attribute set
public Foo(int first, int second)
{
//do the actual initialization
}
public Foo(int first)
{
this(first, DEFAULT_SECOND);
}
public Foo()
{
this(DEFAULT_FIRST, DEFAULT_SECOND);
}
}
Upvotes: 0
Reputation: 46183
In order to invoke a constructor within another one:
this(args)
.You must invoke it as the first statement in the constructor.
Node(K data) {
this();
this.data = data;
}
Upvotes: 2