Should inherited constructor be called in this situation?

Discussion in 'Java' started by Steve Sobol, Aug 21, 2005.

  1. Steve Sobol

    Steve Sobol Guest

    Using reflection...

    Class c=Class.forName(classname,false,new URLClassLoader(urlList));
    // Get a declared zero-arg constructor
    try {
    newPlugin = c.getDeclaredConstructor(null).newInstance(null);
    } catch(NoSuchMethodException e) {
    throw new PluginException(c.getCanonicalName() +
    " has no declared zero-argument constructor");
    } catch(InvocationTargetException e) {
    throw new PluginException("Could not call constructor for " +
    c.getCanonicalName());
    }


    newPlugin is an instance of Class B, which extends class A.

    When I call newInstance, class A's constructor is called first, then class
    B's constructor, even though Class B doesn't have a call to super().

    If I remove Class B's constructor, class A's instructor is still called. I'd
    have expected getDeclaredConstructor to throw an exception or return null if
    there was no actual constructor declared in B...

    Is this the correct behavior?

    --
    Steve Sobol, Professional Geek 888-480-4638 PGP: 0xE3AE35ED
    Company website: http://JustThe.net/
    Personal blog, resume, portfolio: http://SteveSobol.com/
    E: Snail: 22674 Motnocab Road, Apple Valley, CA 92307
     
    Steve Sobol, Aug 21, 2005
    #1
    1. Advertising

  2. Steve Sobol wrote:
    > Using reflection...
    >
    > Class c=Class.forName(classname,false,new URLClassLoader(urlList));
    > // Get a declared zero-arg constructor
    > try {
    > newPlugin = c.getDeclaredConstructor(null).newInstance(null);
    > } catch(NoSuchMethodException e) {
    > throw new PluginException(c.getCanonicalName() +
    > " has no declared zero-argument constructor");
    > } catch(InvocationTargetException e) {
    > throw new PluginException("Could not call constructor for " +
    > c.getCanonicalName());
    > }
    >
    >
    > newPlugin is an instance of Class B, which extends class A.
    >
    > When I call newInstance, class A's constructor is called first, then
    > class B's constructor, even though Class B doesn't have a call to super().
    >
    > If I remove Class B's constructor, class A's instructor is still called.
    > I'd have expected getDeclaredConstructor to throw an exception or return
    > null if there was no actual constructor declared in B...
    >
    > Is this the correct behavior?
    >


    Yes. There are two default rules in operation here:

    1. The first statement in the body of every constructor, except in class
    java.lang.Object, is a constructor invocation using "super" or "this".
    If the constructor body does not begin with an explicit constructor
    invocation, and the class is not java.lang.Object, the compiler inserts
    one equivalent to "super();".

    B's constructor is really called first, but its implicit first statement
    is "super();", so the rest of its body does not execute until A's has
    executed.

    2. Each class contains at least one constructor. If there is no
    explicitly declared constructor, the compiler creates a default
    constructor that takes no parameters and only contains "super();".

    That is the constructor your getDeclaredConstructor call finds when B
    has no explicit constructor declarations.

    Patricia
     
    Patricia Shanahan, Aug 21, 2005
    #2
    1. Advertising

  3. Steve Sobol wrote:
    >
    > If I remove Class B's constructor, class A's instructor is still called.
    > I'd have expected getDeclaredConstructor to throw an exception or return
    > null if there was no actual constructor declared in B...
    >
    > Is this the correct behavior?
    >


    public class Parent()
    {
    public Parent(int i)
    {
    // Some code
    }
    }

    public class Child extends Parent
    {
    }

    You'll find that the class Child will fail to compile even if it
    contains nothing in its body :)

    Illustrates bothe the points which Patricia mentioned. The class Child
    implicitly contains a constructor :

    public Child()
    {
    super();
    }

    whereas the class Parent *does not have* this constructor because the
    class already contains an explicitly declared constructor. So the
    super() call in the Child class is illegal and causes a compiler error.

    (Also there is a hidden super() call inside the "Parent" class's
    declared constructor as its first line if you haven't put anything in
    explicitly)

    BK
     
    Babu Kalakrishnan, Aug 22, 2005
    #3
  4. Steve Sobol

    Roedy Green Guest

    On Sun, 21 Aug 2005 13:22:10 -0700, Steve Sobol <>
    wrote or quoted :

    >When I call newInstance, class A's constructor is called first, then class
    >B's constructor, even though Class B doesn't have a call to super().


    If you look at the classes with a decompiler the mysteries should come
    clear. There are hidden constructors and hidden calls to super().

    See http://mindprod.com/jgloss/constructor.html
     
    Roedy Green, Aug 22, 2005
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. TechCrazy
    Replies:
    5
    Views:
    409
    Karl Heinz Buchegger
    Jul 15, 2005
  2. iTooo
    Replies:
    4
    Views:
    536
    Peter_Julian
    Nov 5, 2005
  3. Generic Usenet Account
    Replies:
    10
    Views:
    2,341
  4. geekbuntu
    Replies:
    11
    Views:
    460
    Lawrence D'Oliveiro
    Oct 7, 2010
  5. 7stud --
    Replies:
    11
    Views:
    465
    7stud --
    Nov 9, 2007
Loading...

Share This Page