• Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Constructor Question

 
Russ Russell
Ranch Hand
Posts: 72
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
In the SCJP Study Guide it says: "You cannot make a call to an instance method, or access an instance variable, until after the super constructor runs." (Earlier, it mentions that a call to super() is inserted by the compiler.)

But isn't that just a logistical issue? By definition instance variables need an instance of the class to be accessed. How else would I access them unless the constructor has run (which means I made an instance)?

Thank you,
-Russ


 
Keith Rainey
Ranch Hand
Posts: 66
Android Eclipse IDE IntelliJ IDE
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think the point is that all constructors higher in the hierarchy must complete before you can access instance members. The implicit super() (or explicit super() if you put it in there yourself), must be the first line in the constructor, otherwise it will not compile.


Pay good attention to constructor chaining in your SCJP prep.
 
Russ Russell
Ranch Hand
Posts: 72
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you Keith.

Doesn't the implicit super() or explicit super() run only if an instance is created usng "new"? If so, how would I possibly access any instance members without creating an instance using new? ClasssName.member only works for non-instance menbers.

It's as if the book is warning me against attempting to do something that's impossible to do anyway. I mean, once the constructor chaining begins, I can't interrupt it.

Thanks again,
-Russ
 
Keith Rainey
Ranch Hand
Posts: 66
Android Eclipse IDE IntelliJ IDE
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Russ Russell wrote:In the SCJP Study Guide it says: "You cannot make a call to an instance method, or access an instance variable, until after the super constructor runs."



I interpreting that to mean you can't access instance members from within the constructor until the supers complete their run.

It's as if the book is warning me against attempting to do something that's impossible to do anyway.

If there's a way to do it, I can't think of it.

I'm not sure how to elaborate on that. What page are you reading from in the SCJP book? I'll check it out in its complete context when I get home later.
 
Russ Russell
Ranch Hand
Posts: 72
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
It's on page 134. The 5th bullet down.
It could be I'm simply misinterpreting the grammer.

Thanks again!
-Russ
 
Joanne Neal
Rancher
Pie
Posts: 3742
16
  • 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Russ Russell wrote:By definition instance variables need an instance of the class to be accessed. How else would I access them unless the constructor has run (which means I made an instance)?

Despite their name, constructors do not create an instance of a class - they only initialise it. At the time the constructor is called the class instance and all it's member variables already exist. The need to make a call to super() before doing anything else in the constructor is to make sure all the members of the parent class(es) are correctly initialised first.
 
Paul Clapham
Sheriff
Pie
Posts: 20169
24
MySQL Database
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Keith Rainey wrote:
Russ Russell wrote:In the SCJP Study Guide it says: "You cannot make a call to an instance method, or access an instance variable, until after the super constructor runs."



I interpreting that to mean you can't access instance members from within the constructor until the supers complete their run.

It's as if the book is warning me against attempting to do something that's impossible to do anyway.

If there's a way to do it, I can't think of it.


It isn't impossible. The way to do it is to have the constructor of the super-class of your class call an instance method which is overridden by your class. Things can get confusing real fast if you do this.
 
Rob Spoor
Sheriff
Pie
Posts: 20372
44
Chrome Eclipse IDE Java Windows
  • 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
An example:
As you'll see, the first time Sub.doSomething() is called, i and s will not have been initialized yet, and their values will be 0 and null respectively. Only after the implicit (or explicit) call to super() has ended will i and s get their values.
That's why methods shouldn't be called from any constructor unless
a) they are private, and therefore cannot be overridden
b) they are final, and therefore cannot be overridden

There is a questionable option c) that would allow it if it's properly documented that it can / will be called from a constructor, and therefore overriding methods should not use any fields (directly or indirectly through other method calls), but I think the majority of people will say it's not a valid option.
 
Randall Twede
Ranch Hand
Posts: 4353
2
Java
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
that explains a question i also had. i have called private methods from constructors and was wondering about calling public ones(instead of calling them from main()).
 
Russ Russell
Ranch Hand
Posts: 72
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you Rob Spoor. I can't quite understand how it works yet, but yes, you have code running before the constructor ran. Is it because when the Super constructor calls doSomething(), it is calling Sub's doSomething()?

Thank you,
-Russ
 
Rob Spoor
Sheriff
Pie
Posts: 20372
44
Chrome Eclipse IDE Java Windows
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Exactly.
 
Campbell Ritchie
Sheriff
Pie
Posts: 47229
52
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If you look through the Java Language Specification (JLS), you will find the official line about constructors. The JLS is not easy to understand, I am afraid.
 
Russ Russell
Ranch Hand
Posts: 72
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rob,

It's hard for me to understand why Super calling doSomething() would invoke Sub's version of doSomething() instead of its own version. Can you tell me? I mean, Sub inherits Super. Not the other way around.

Thanks again,
-Russ
 
Rob Spoor
Sheriff
Pie
Posts: 20372
44
Chrome Eclipse IDE Java Windows
  • 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Because doSomething is overridden, and even though the constructor is that of class Super, the current object inside that Super constructor is still a Sub instance.
 
Russ Russell
Ranch Hand
Posts: 72
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Rob Spoor wrote:the current object inside that Super constructor is still a Sub instance.


Would you point out to me where in your example I can see this? Thanks.
 
Rob Spoor
Sheriff
Pie
Posts: 20372
44
Chrome Eclipse IDE Java Windows
  • 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
 
Russ Russell
Ranch Hand
Posts: 72
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thank you again Rob.

Is Super inheriting Sub's doSomething()? How can Super be a Sub when class Sub extends Super?
The closest thing I've seen to this was in the Polymorphism chapter when you have something like Super s = new Sub();

Thank you,
-Russ
 
Rob Spoor
Sheriff
Pie
Posts: 20372
44
Chrome Eclipse IDE Java Windows
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think you're missing the big picture here.

When you create a new Sub, it goes through these steps:
1) call super() - in other words, the Super constructor.
1a) call getClass() which returns the class of the new Sub object.
1b) call doSomething() which is the overridden method of the new Sub object.
2) initialize i and s.
3) print out i and s.
 
Russ Russell
Ranch Hand
Posts: 72
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks for clearing this up for me Rob.

-Russ
 
Rob Spoor
Sheriff
Pie
Posts: 20372
44
Chrome Eclipse IDE Java Windows
  • 0
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You're welcome.
 
Consider Paul's rocket mass heater.
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic