• Post Reply Bookmark Topic Watch Topic
  • New Topic

Constructor chaining  RSS feed

 
Brian K Smith
Greenhorn
Posts: 12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
An elementary concept in constructors is that any call to super() or this() must be the first line in the constructor. Obviously, this means you can have only one. The following will not compile.

public class foo{

public static void main(String[] args) {

bar mybar = new bar();
}

}

class bar extends foo{

private String name;

bar(String s) {
name = s;
}

bar(){
super();
this("default");
}

}

Why exactly? If I had the following:

bar(){

this("default");
}

the compiler would automatically put in a call to super, specifically a call to the no args constructor. Why by rule can we not do this manually? The bit of web research I did just asserted the elementary rule I talked about up top, and my book just asserts it as well. It doesn't seem to me like it would violate constructor chaining. What *would* do that would be allowing something like:

bar() {
this("default");
super();
}

Now that would cause a headache! Did the designers of Java just put in the rule this() or super() must be first to make it an easier language to implement, or am I missing something deeper?

Thanks.

Since a call to the no-args super constructor is automatically inserted by the compiler

 
Stephan van Hulst
Saloon Keeper
Posts: 7974
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It isn't always inserted by the compiler. It's inserted implicitly only when you aren't already calling this() or super() yourself.

The reason super() (or this()) has to be in the first line of the constructor, is because the object will not be in a consistent state before the call to a super constructor. You are not allowed to use members of an inconsistent object, because it may break the object.
 
Brian K Smith
Greenhorn
Posts: 12
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:It isn't always inserted by the compiler. It's inserted implicitly only when you aren't already calling this() or super() yourself.


Right. I should've said that explicitly. In the above example the compiler would insert it as there was no call to this() or super()

Stephan van Hulst wrote:
The reason super() (or this()) has to be in the first line of the constructor, is because the object will not be in a consistent state before the call to a super constructor. You are not allowed to use members of an inconsistent object, because it may break the object.


Not to be difficult, but what exactly does it mean for an object to "be in a consistent state"? or what are some resources I could look at for an answer?
 
Stephan van Hulst
Saloon Keeper
Posts: 7974
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Well, it's abstract. Whoever designs a class decides what it means for an object to be in a consistent state. Whatever it is, it usually can't be done without the constructor.

When the object is consistent, it means that all its fields (and that of its super) have values that make sense. Consider this example:

Mini attempts to drive around before the super constructor is called. Since the object is still in an inconsistent state, this is sure to throw a NullPointerException when a new Mini is created.
 
Jesper de Jong
Java Cowboy
Sheriff
Posts: 16059
88
Android IntelliJ IDE Java Scala Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Brian, welcome to JavaRanch. Please UseCodeTags when you post source code.
 
marc weber
Sheriff
Posts: 11343
Java Mac Safari
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Brian K Smith wrote:...If I had the following:

bar(){
this("default");
}

the compiler would automatically put in a call to super, specifically a call to the no args constructor. Why by rule can we not do this manually? ...

The compiler would not insert a call to super() here, because "this" is present.

At least one constructor must call super (explicitly or implicitly), because an instance of the superclass must be created before the subclass can be created. So a constructor starts either by calling a superclass constructor (which can be explicit using "super" or implicit with the compiler inserting a no-args call) or by calling an overloaded version of itself. Using "this" essentially passes the responsibility of calling super to an overloaded version of the constructor.

If a constructor could call both, "this" and "super," then we could end up with multiple instances of the superclass -- one created using "super," and one (or more) created by the overloaded constructor also calling "super."
 
Campbell Ritchie
Marshal
Posts: 56536
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote: . . .
. . . this is sure to throw a NullPointerException when a new Mini is created.
More likely it won't compile, since super() or this() are only allowed as the first statement in a constructor.
 
Stephan van Hulst
Saloon Keeper
Posts: 7974
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I know, I was just showing what would happen if it *was* allowed.
 
Don't get me started about those stupid light bulbs.
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!