• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Jeanne Boyarsky
  • Liutauras Vilda
  • Campbell Ritchie
  • Tim Cooke
  • Bear Bibeault
Sheriffs:
  • Paul Clapham
  • Junilu Lacar
  • Knute Snortum
Saloon Keepers:
  • Ron McLeod
  • Ganesh Patekar
  • Tim Moores
  • Pete Letkeman
  • Stephan van Hulst
Bartenders:
  • Carey Brown
  • Tim Holloway
  • Joe Ess

Constructor chaining  RSS feed

 
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

 
Saloon Keeper
Posts: 9137
172
  • 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: 9137
172
  • 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.
 
Java Cowboy
Sheriff
Posts: 16084
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.
 
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."
 
Marshal
Posts: 59762
188
  • 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: 9137
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I know, I was just showing what would happen if it *was* allowed.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!