Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / April 2007

Tip: Looking for answers? Try searching our database.

Sequence of calling super's constructor in Java

Thread view: 
Sathyaish - 05 Apr 2007 14:35 GMT
I have some questions about calling constructors in Java:

1) Do I *have* to call the base/super class constructor from the
child's constructor as the *first* line of code or can I call it
afterwards also from within the child class' constructor?

As in, do I have to do this?

class Child extends Parent
{
   public Child(somearg)
   {
       /* call the parent's constructor first */
       super(somearg);

       /* other stuff here */
   }
}

Or do I have the liberty to do this?

class Child extends Parent
{
   public Child(somearg)
   {
       /* some stuff first happens here */

       /* later */
       super(somearg);
   }
}

I recall reading somewhere that the call to super has to be first line
of code in a child's constructor.

2) Does Java implicitly call super even when we don't explicitly call
it from a child? It makes sense because that is how object invocation
is sequenced. However, how does it know the params to pass? Or does it
do it call the non-parameterized constructor of the super class?
Because how else will it know of what parameters to pass?

3) Supposing the answer to question 2 above is "Yes, Java does call
non-parameterized constructors implicitly first, in order to create
the parent before creating the child," even then, can I explicitly
call the parent's constructor as indicated in question (1) (b) above?
Sathyaish - 05 Apr 2007 15:03 GMT
*PARTLY RESOLVED*

This quote:

Note: If a constructor does not explicitly invoke a superclass
constructor, the Java compiler automatically inserts a call to the no-
argument constructor of the superclass. If the super class does not
have a no-argument constructor, you will get a compile-time error.
Object does have such a constructor, so if Object is the only
superclass, there is no problem.

from this link: http://java.sun.com/docs/books/tutorial/java/IandI/super.html

answers questions (2) and (3).

Can someone please answer my question (1).
Sathyaish - 05 Apr 2007 15:15 GMT
*FULLY RESOLVED*

1. Yes. It has to be the first statement.

2. As indicated by the note and the link above, Java will call the
base's non-parameterized constructor implicitly if a parameterized one
is not called as the first line of code. If the base class is a class
other than System.Object and the base class doesn't have one, it'll
complain.

3. If the base's parameterized constructor is called by the child's
constructor as the first line explicitly, no problem. If the base's
parameterized constructor is called explicitly by the child *later*
than the first line, the compiler will complain because it will expect
JRE to instantiate the object already in the first line by the
implicit call to the naked constructor.
Eric Sosman - 05 Apr 2007 20:20 GMT
Sathyaish wrote On 04/05/07 10:15,:
> *FULLY RESOLVED*
>
> 1. Yes. It has to be the first statement.

   (It would be nicer to quote enough context so someone
can know what Question 1 is without scrambling backwards
through the thread thickets ...)

   For those tuning in late, Question 1 asked whether the
call to the superclass constructor had to be the first
statement in a subclass constructor, or whether it could
come later.  As Sathyaish has discovered, it must be first.

   In some cases, you may need to execute a few statements
to generate the arguments you need for the super-constructor.
You cannot do something like

    SubClass(double[] array) {
       double total = 0;
       for (double d : array)
           total += d;
       // pass array average to superclass constructor:
       super(total / array.length);
       ...
    }

... because the call to super is not first.  What you *can*
do, though, is move the interfering statements to a method
of their own:

    SubClass(double[] array) {
       super(meanOfArray(array));
       ...
    }

    private static double meanOfArray(double[] array) {
       ... find and return the mean ...
    }

   If you need to use this trick, make sure that the "helper"
method cannot be overridden in a sub-subclass!  It will run
before the SubClass instance is fully initialized -- even
before the SuperClass instance is initialized -- so you can
get lots of peculiar trouble if it tries to do something with
the incompletely initialized object.  Making it private and/or
static, as above, is a good defense against that error.

Signature

Eric.Sosman@sun.com

Lew - 05 Apr 2007 22:40 GMT
>     If you need to use this trick, make sure that the "helper"
> method cannot be overridden in a sub-subclass!  It will run
[quoted text clipped - 3 lines]
> the incompletely initialized object.  Making it private and/or
> static, as above, is a good defense against that error.

Joshua Bloch goes into this point in /Effective Java/.

Never call overridable methods from a constructor.

Generally, don't do very much work in the constructor.  Never do work in the
constructor not related to construction of the object.

Signature

Lew

Piotr Kobzda - 06 Apr 2007 08:17 GMT
>>     If you need to use this trick, make sure that the "helper"
>> method cannot be overridden in a sub-subclass!  It will run
[quoted text clipped - 3 lines]
>> the incompletely initialized object.  Making it private and/or
>> static, as above, is a good defense against that error.

Making it static is the only choice for a "trick", hence it can not be
overridden.  Instance of the class being initialized is not yet
available, so worry about its initialization is not needed here.

> Joshua Bloch goes into this point in /Effective Java/.
>
> Never call overridable methods from a constructor.

That's impossible in Eric's "trick".

    SubClass() {  // constructor
        SuperClass( /* 'this' is not available here! */ );

        // that's what J. Bloch is dissuading from doing
        overridableMethod();
        ...

> Generally, don't do very much work in the constructor.  Never do work in
> the constructor not related to construction of the object.

Agreed.

piotr
Piotr Kobzda - 06 Apr 2007 12:55 GMT
>> Joshua Bloch goes into this point in /Effective Java/.
>>
>> Never call overridable methods from a constructor.
>
> That's impossible in Eric's "trick".

Or, that's the only possibility for a "trick".  The answer depends what
sense of the statement it refers to.[1]  :)

>     SubClass() {  // constructor
>         SuperClass( /* 'this' is not available here! */ );

Of course, correct syntax is:

          super( /* 'this' is not available here! */ );

>         // that's what J. Bloch is dissuading from doing
>         overridableMethod();
>         ...

piotr

[1] -- I don't know, if for all English speakers the main sense
distinction is obvious here -- for me, it isn't.  English is not my
native language, hence it sometimes appears difficult to me to get a
right sense of the sentence, especially in context of discussion in mind.

BTW, it sometimes happens also that my English sentences are not correct
(even though I'm hardly trying to avoid it), and they are possibly not
even understandable for others.  My apologies to all for that.
Gordon Beaton - 06 Apr 2007 13:51 GMT
> BTW, it sometimes happens also that my English sentences are not
> correct (even though I'm hardly trying to avoid it), and they are
> possibly not even understandable for others.

I don't normally comment on language style, but just couldn't resist
here, given the context: "hardly trying" means the opposite of "trying
hard", which is what I think you meant to say.

/gordon

--
Piotr Kobzda - 06 Apr 2007 14:40 GMT
> I don't normally comment on language style, but just couldn't resist
> here, given the context: "hardly trying" means the opposite of "trying
> hard", which is what I think you meant to say.

Yes, that's what I meant. :)  Thanks!

piotr
Chris Uppal - 06 Apr 2007 09:07 GMT
>     If you need to use this trick, make sure that the "helper"
> method cannot be overridden in a sub-subclass!

The compiler won't let you call code which could be overriden in this trick.
It is illegal (rejected by the verifier even if the compiler allowed it) to
make any use of "this" before the superclass constructor has been called[*].
So you are restricted to using static methods, or code which otherwise makes no
reference to the object under construction.

   -- chris

[*] There are a few technical quibbles here, but they probably aren't relevant
for this thread.


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2009 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.