calling own methods from constructor

Discussion in 'Java' started by Andreas Leitgeb, Apr 6, 2011.

  1. There is well-known danger in calling own methods from the
    constructor, namely that the method called may be overridden
    by a subclass, which is really instanciated, but whose specific
    constructor has not yet been run.

    I do not intend to delve into the details of static, private
    or final methods, or final'ity of the class itself (and maybe
    others) avoiding these problems, but instead I'm curious, why
    Java just doesn't simply forbid the dangerous calls.

    Is there any *good* use of having the constructor call a method
    that actually *can* be overridden in a subclass? I mean, are
    there (non-anti)patterns of explicitly allowing subclasses to
    hook into base-class's construction?

    --- sscce Test.java begin ---
    public class Test {
    Test() { foo(); }
    void foo() { }
    }
    --- sscce Test.java end ---

    PS: I know that this is not the only spot where Java does let one
    shoot in one's feet. But unlike other situations, this one just
    seems so easy to detect from static analysis.
     
    Andreas Leitgeb, Apr 6, 2011
    #1
    1. Advertising

  2. Andreas Leitgeb

    Tom Anderson Guest

    On Wed, 6 Apr 2011, Andreas Leitgeb wrote:

    > Is there any *good* use of having the constructor call a method that
    > actually *can* be overridden in a subclass? I mean, are there
    > (non-anti)patterns of explicitly allowing subclasses to hook into
    > base-class's construction?


    public abstract class Library {
    private List<Document> documents;

    protected Library() {
    documents = new ArrayList<Document>();
    Collection<String> titles = listDocuments();
    for (String title: titles) {
    Document doc = loadDocument(title);
    // do other preparatory stuff with the document
    documents.add(doc);
    }
    }

    protected abstract Collection<String> listDocuments();
    protected abstract Document loadDocument(String title);
    }

    public class FilesystemLibrary extends Library {
    // ...
    }

    public class WebDavLibrary extends Library {
    // ...
    }

    public class JCRLibrary extends Library {
    // ...
    }

    What are the alternatives?

    The obvious one is for the subclass constructor to prepare all the objects
    and pass them upward; i think that is likely to lead to a lot of
    duplication of effort.

    The almost as obvious one is to push the abstract methods out into a
    separate interface - DocumentStore, say - and have the subclass
    constructor pass up an instance of that.

    You could also push the repeated logic out into some sort of factory or
    helper, and have the subclasses call that, rather than relying on code in
    the supeclass, but that is repetitive, and does nothing to establish
    invariants in the superclass.

    tom

    --
    Science which is distinguishable from magic is insufficiently advanced
     
    Tom Anderson, Apr 6, 2011
    #2
    1. Advertising

  3. Andreas Leitgeb

    Lew Guest

    Andreas Leitgeb wrote:
    >> Is there any *good* use of having the constructor call a method that
    >> actually *can* be overridden in a subclass? I mean, are there
    >> (non-anti)patterns of explicitly allowing subclasses to hook into
    >> base-class's construction?


    import org.apache.log4j.Logger;
    import static org.apache.log4j.getLogger;

    public class Foo
    {
    private final Logger logger = getLogger( getClass() );
    // ...
    }


    --
    Lew
    Honi soit qui mal y pense.
    http://upload.wikimedia.org/wikipedia/commons/c/cf/Friz.jpg
     
    Lew, Apr 6, 2011
    #3
  4. Andreas Leitgeb

    Eric Sosman Guest

    On 4/6/2011 6:06 PM, Tom Anderson wrote:
    > On Wed, 6 Apr 2011, Andreas Leitgeb wrote:
    >
    >> Is there any *good* use of having the constructor call a method that
    >> actually *can* be overridden in a subclass? I mean, are there
    >> (non-anti)patterns of explicitly allowing subclasses to hook into
    >> base-class's construction?

    >
    > public abstract class Library {
    > private List<Document> documents;
    >
    > protected Library() {
    > documents = new ArrayList<Document>();
    > Collection<String> titles = listDocuments();
    > for (String title: titles) {
    > Document doc = loadDocument(title);
    > // do other preparatory stuff with the document
    > documents.add(doc);
    > }
    > }
    >
    > protected abstract Collection<String> listDocuments();
    > protected abstract Document loadDocument(String title);
    > }
    >
    > public class FilesystemLibrary extends Library {
    > // ...
    > }
    >
    > public class WebDavLibrary extends Library {
    > // ...
    > }
    >
    > public class JCRLibrary extends Library {
    > // ...
    > }
    >
    > What are the alternatives?


    Safer ones, I hope. This code presupposes that the subclass
    instance can do useful work before its constructor finishes -- to
    put it another way, it assumes that the subclass constructor does
    absolutely nothing except call the superclass constructor (and even
    that much requires some leaps of faith).

    How might Java ensure such an assumption? I can't imagine how
    it could be done at compile time, when the suite of subclasses may
    not even exist to be inspected. At run time, I guess it could be
    done with two additional bits per instance: One that says "The
    constructor has not yet returned" and another that says "A virtual
    method has been called while the constructor is active." Each
    virtual method would copy the first bit to the second, and if the
    constructor found the second bit set while doing anything other
    than a "return," it could throw an exception.

    > The obvious one is for the subclass constructor to prepare all the
    > objects and pass them upward; i think that is likely to lead to a lot of
    > duplication of effort.
    >
    > The almost as obvious one is to push the abstract methods out into a
    > separate interface - DocumentStore, say - and have the subclass
    > constructor pass up an instance of that.
    >
    > You could also push the repeated logic out into some sort of factory or
    > helper, and have the subclasses call that, rather than relying on code
    > in the supeclass, but that is repetitive, and does nothing to establish
    > invariants in the superclass.


    It seems to me the constructor is doing too much of the heavy
    lifting. A Library(Collection<Document>) constructor, with the
    Documents already loaded or maybe with "load on first use" flags,
    seems a more tenable approach. In particular, it allows the
    subclass constructors to choose their own sets of exceptions to
    throw, instead of requiring that they all extend exceptions thrown
    by the superclass' abstract method declarations.

    --
    Eric Sosman
    d
     
    Eric Sosman, Apr 7, 2011
    #4
  5. On 2011-04-06 16:48:41 -0400, Andreas Leitgeb said:

    > There is well-known danger in calling own methods from the
    > constructor, namely that the method called may be overridden
    > by a subclass, which is really instanciated, but whose specific
    > constructor has not yet been run.
    >
    > I do not intend to delve into the details of static, private
    > or final methods, or final'ity of the class itself (and maybe
    > others) avoiding these problems, but instead I'm curious, why
    > Java just doesn't simply forbid the dangerous calls.


    It's hard to prove that a constructor never calls a virtual method. Consider:

    public class Foo {
    public Foo() {
    // internalInit is private, therefore final
    this.internalInit();
    }

    public /* virtual */ void virtualMethod() {
    System.out.println("Override me! I dare you.");
    }

    private void internalInit() {
    // Whups! 'this' is not always fully initialized.
    this.virtualMethod();
    }
    }

    If you forbid internalInit from calling virtual methods because it is,
    itself, called from a constructor, you also prevent it from calling
    virtual methods when called from a normal method. If you don't prevent
    that, but do prevent Foo's constructor from calling any of its own
    virtual methods, then you end up with the question "why does Java make
    me use a private method when I want to call a virtual method from a
    constructor?" instead.

    -o
     
    Owen Jacobson, Apr 7, 2011
    #5
  6. Tom Anderson <> wrote:
    > On Wed, 6 Apr 2011, Andreas Leitgeb wrote:
    >> Is there any *good* use of having the constructor call a method that
    >> actually *can* be overridden in a subclass? I mean, are there
    >> (non-anti)patterns of explicitly allowing subclasses to hook into
    >> base-class's construction?


    > public abstract class Library {
    > private List<Document> documents;
    > protected Library() {
    > documents = new ArrayList<Document>();
    > Collection<String> titles = listDocuments();
    > for (String title: titles) {
    > Document doc = loadDocument(title);
    > // do other preparatory stuff with the document
    > documents.add(doc);
    > }
    > }
    > protected abstract Collection<String> listDocuments();
    > protected abstract Document loadDocument(String title);
    > }
    >
    > public class FilesystemLibrary extends Library {
    > // ...
    > }
    > [...]


    Sorry, in my eyes, this is one of the anti-patterns.

    > What are the alternatives?


    It's hard to speculate about alternatives for an artificial example.

    I'd say, that they exist for any reasonable specification of the problem,
    and "back it up"(*) by declaring specifications for which no (or only
    mindboggingly contrived) alternatives exist as unreasonable ;-)

    (*): In German, we use double-quotes also to indicate tongue-in-cheek
    formulations that aren't to be taken entirely literally/serious.
    I've recently learned that they are not always thusly understood,
    elsewhere. Therefore this explanation. Is there any common markup
    for it that would be recognized in the English-speaking world?
     
    Andreas Leitgeb, Apr 7, 2011
    #6
  7. Lew <> wrote:
    > Andreas Leitgeb wrote:
    >>> Is there any *good* use of having the constructor call a method that
    >>> actually *can* be overridden in a subclass? I mean, are there
    >>> (non-anti)patterns of explicitly allowing subclasses to hook into
    >>> base-class's construction?

    >
    > import org.apache.log4j.Logger;
    > import static org.apache.log4j.getLogger;
    > public class Foo
    > {
    > private final Logger logger = getLogger( getClass() );
    > // ...
    > }


    I thought, I made it clear, that calling static methods was not relevant
    to my question. So, kind of thanks for pointing out that I should have
    written non-static in the very line of the question, rather than consider
    that clear from the other (snipped by you) paragraphs of my post...
     
    Andreas Leitgeb, Apr 7, 2011
    #7
  8. Owen Jacobson <> wrote:
    > On 2011-04-06 16:48:41 -0400, Andreas Leitgeb said:
    >
    >> There is well-known danger in calling own methods from the
    >> constructor, namely that the method called may be overridden
    >> by a subclass, which is really instanciated, but whose specific
    >> constructor has not yet been run.
    >>
    >> I do not intend to delve into the details of static, private
    >> or final methods, or final'ity of the class itself (and maybe
    >> others) avoiding these problems, but instead I'm curious, why
    >> Java just doesn't simply forbid the dangerous calls.

    >
    > It's hard to prove that a constructor never calls a virtual method. Consider:
    > [ example of c'tor calling a private method "internalInit", which in turn
    > calls virtual "virtualMethod". ]


    Good point. The compiler couldn't (at least not statically) prevent
    indirect calling of overridable non-static methods.

    But otoh., it refuses to compile this:
    String bad = (String) new Integer(42);
    while allowing this: (sure bomb at runtime)
    String bad = (String) (Object) new Integer(42);

    So, not being able to prevent something happening indirectly,
    doesn't imply that the direct way would need to be allowed, too.

    So, it boils down to the original question of whether there is also
    a good use of constructors (directly or indirectly) invoking
    overridable virtual methods.

    What it "good"? I have no exact definition, but if one of the
    Java gurus (Brian Goetz, Joshua Bloch, James Gosling,...) ever
    before suggested a pattern that would involve it, then chances
    are good, that I'd accept it. Also, if the JSL or one of the big
    Java-based projects used it. Tom's example (Library) didn't
    convince me so far.
     
    Andreas Leitgeb, Apr 7, 2011
    #8
  9. On 11-04-07 05:36 AM, Andreas Leitgeb wrote:
    [ SNIP ]

    > (*): In German, we use double-quotes also to indicate tongue-in-cheek
    > formulations that aren't to be taken entirely literally/serious.
    > I've recently learned that they are not always thusly understood,
    > elsewhere. Therefore this explanation. Is there any common markup
    > for it that would be recognized in the English-speaking world?


    It would be quotation marks, usually double quotes, just as in German.
    Even Wikipedia (in its entry for Quotation Marks) refers to the use of
    quotation not only for actual quotes, but also to denote irony or
    unusual usage. Quotes are also used to indicate non-literal or
    self-coined meanings, or to emphasize use of the word rather than its
    meaning.

    Having said that, there are varying levels of literacy in the
    English-speaking world. Not everyone will be aware of the other usages
    for quotation marks.

    AHS
    --
    That's not the recollection that I recall...All this information is
    certainly in the hands of the auditor and we certainly await his report
    to indicate what he deems has occurred.
    -- Halifax, Nova Scotia mayor Peter Kelly, who is currently deeply in
    the shit
     
    Arved Sandstrom, Apr 7, 2011
    #9
  10. Andreas Leitgeb

    Roedy Green Guest

    On 06 Apr 2011 20:48:41 GMT, Andreas Leitgeb
    <> wrote, quoted or indirectly quoted
    someone who said :

    >Is there any *good* use of having the constructor call a method
    >that actually *can* be overridden in a subclass?


    I have accidentally nailed myself by overriding a method used in a
    constructor. I have yet to find a legitimate use for it. It is too
    bad the compiler does not complain about it.
    --
    Roedy Green Canadian Mind Products
    http://mindprod.com
    Doing what the user expects with respect to navigation is absurdly important for user satisfaction.
    ~ anonymous Google Android developer
     
    Roedy Green, Apr 7, 2011
    #10
  11. Andreas Leitgeb

    Paul Cager Guest

    On Apr 7, 9:36 am, Andreas Leitgeb <>
    wrote:
    ....
    > I'd say, that they exist for any reasonable specification of the problem,
    > and "back it up"(*) by declaring specifications for which no (or only
    > mindboggingly contrived) alternatives exist as unreasonable ;-)
    >
    > (*): In German, we use double-quotes also to indicate tongue-in-cheek
    > formulations that aren't to be taken entirely literally/serious.
    > I've recently learned that they are not always thusly understood,
    > elsewhere.  Therefore this explanation. Is there any common markup
    > for it that would be recognized in the English-speaking world?


    I think we use the same convention in British English. I'm not certain
    about our "colonial cousins".

    The convention also spills over into spoken English, often using non-
    verbal hints. There was also a fad at one time for people to raise
    their hands to either side of their head and wriggle two fingers to
    imitate quotes. I believe it's only used ironically now.
     
    Paul Cager, Apr 7, 2011
    #11
  12. Andreas Leitgeb

    Tobias Blass Guest

    On 2011-04-07, Andreas Leitgeb <> wrote:
    > Owen Jacobson <> wrote:
    >> On 2011-04-06 16:48:41 -0400, Andreas Leitgeb said:
    >>
    >>> There is well-known danger in calling own methods from the
    >>> constructor, namely that the method called may be overridden
    >>> by a subclass, which is really instanciated, but whose specific
    >>> constructor has not yet been run.
    >>>
    >>> I do not intend to delve into the details of static, private
    >>> or final methods, or final'ity of the class itself (and maybe
    >>> others) avoiding these problems, but instead I'm curious, why
    >>> Java just doesn't simply forbid the dangerous calls.

    >>
    >> It's hard to prove that a constructor never calls a virtual method. Consider:
    >> [ example of c'tor calling a private method "internalInit", which in turn
    >> calls virtual "virtualMethod". ]

    >
    > Good point. The compiler couldn't (at least not statically) prevent
    > indirect calling of overridable non-static methods.
    >
    > But otoh., it refuses to compile this:
    > String bad = (String) new Integer(42);
    > while allowing this: (sure bomb at runtime)
    > String bad = (String) (Object) new Integer(42);
    >
    > So, not being able to prevent something happening indirectly,
    > doesn't imply that the direct way would need to be allowed, too.
    >
    > So, it boils down to the original question of whether there is also
    > a good use of constructors (directly or indirectly) invoking
    > overridable virtual methods.
    >
    > What it "good"? I have no exact definition, but if one of the
    > Java gurus (Brian Goetz, Joshua Bloch, James Gosling,...) ever
    > before suggested a pattern that would involve it, then chances
    > are good, that I'd accept it. Also, if the JSL or one of the big
    > Java-based projects used it. Tom's example (Library) didn't
    > convince me so far.
    >

    Why should it complain about your second example? You tell the Compiler
    explicitly "Please consider this Integer as Object and this Object as String,
    I know types don't match but I know what I'm doing" (I'm programming in C at
    the moment where the Compiler doesn't complain about things javac wouldn't
    even compile as in your first example, so YMMV)
     
    Tobias Blass, Apr 7, 2011
    #12
  13. On 7 Apr., 10:44, Andreas Leitgeb <>
    wrote:
    > Lew <> wrote:
    > > Andreas Leitgeb wrote:
    > >>> Is there any *good* use of having the constructor call a method that
    > >>> actually *can* be overridden in a subclass? I mean, are there
    > >>> (non-anti)patterns of explicitly allowing subclasses to hook into
    > >>> base-class's construction?

    >
    > > import org.apache.log4j.Logger;
    > > import static org.apache.log4j.getLogger;
    > > public class Foo
    > > {
    > >     private final Logger logger = getLogger( getClass() );
    > >   // ...
    > > }

    >
    > I thought, I made it clear, that calling static methods was not relevant
    > to my question.  So, kind of thanks for pointing out that I should have
    > written non-static in the very line of the question, rather than consider
    > that clear from the other (snipped by you) paragraphs of my post...


    Well, that is clear, but: getClass() isn't a static method. Note that
    Lew did not post the usual idiom with log4j and the like which
    typically looks something like this:

    private static final Logger logger = Logger.getLogger(Foo.class);

    As for me, I can't remember having shot myself in the foot with this
    feature of Java (i.e. allowing to invoke virtual methods in
    constructor). I reckon, language designers figured that allowing it
    is more worthwhile than preventing it. As Thomas pointed out you
    would have to provide constructor arguments so subclasses can pass on
    data they have created. This is tiresome and may even end up being
    inefficient namely in the case where the superclass constructor needs
    to decide which methods to call (or whether methods to call). You
    would end up creating objects which then need to be discarded if the
    super class constructor decides that he does not need them =>
    inefficient code.

    Btw, the check would be expensive for the compiler and I am also not
    sure how that byte code might look like because you need to extend the
    restrictions to all methods. Consider

    class Foo {
    private int v;

    public Foo() {
    v = init(); // allowed, because it's private
    }

    public void reinitialize() {
    v = init();
    }

    private int init() {
    // allowed, but only if init() is not invoked
    // from a constructor:
    int x = doSomething();
    return x * 10 + 2;
    }

    /** Sub classes may override this.
    * @return a number
    */
    protected int doSomething() {
    return 5;
    }
    }


    Kind regards

    robert
     
    Robert Klemme, Apr 7, 2011
    #13
  14. Andreas Leitgeb

    Lew Guest

    On 04/07/2011 04:44 AM, Andreas Leitgeb wrote:
    > Lew<> wrote:
    >> Andreas Leitgeb wrote:
    >>>> Is there any *good* use of having the constructor call a method that
    >>>> actually *can* be overridden in a subclass? I mean, are there
    >>>> (non-anti)patterns of explicitly allowing subclasses to hook into
    >>>> base-class's construction?

    >>
    >> import org.apache.log4j.Logger;
    >> import static org.apache.log4j.getLogger;
    >> public class Foo
    >> {
    >> private final Logger logger = getLogger( getClass() );
    >> // ...
    >> }

    >
    > I thought, I made it clear, that calling static methods was not relevant
    > to my question. So, kind of thanks for pointing out that I should have
    > written non-static in the very line of the question, rather than consider
    > that clear from the other (snipped by you) paragraphs of my post...


    I did not realize that 'getClass()' was static.

    --
    Lew
    Honi soit qui mal y pense.
    http://upload.wikimedia.org/wikipedia/commons/c/cf/Friz.jpg
     
    Lew, Apr 7, 2011
    #14
  15. Arved Sandstrom <> wrote:
    > On 11-04-07 05:36 AM, Andreas Leitgeb wrote:
    >> (*): In German, we use double-quotes also to indicate tongue-in-cheek
    >> formulations that aren't to be taken entirely literally/serious.
    >> I've recently learned that they are not always thusly understood,
    >> elsewhere. Therefore this explanation. Is there any common markup
    >> for it that would be recognized in the English-speaking world?

    >
    > It would be quotation marks, usually double quotes, just as in German.
    > Even Wikipedia (in its entry for Quotation Marks) refers to the use of
    > quotation not only for actual quotes, but also to denote irony or
    > unusual usage. Quotes are also used to indicate non-literal or
    > self-coined meanings, or to emphasize use of the word rather than its
    > meaning.


    Thanks for the info!

    > Having said that, there are varying levels of literacy in the
    > English-speaking world. Not everyone will be aware of the other
    > usages for quotation marks.


    :/
     
    Andreas Leitgeb, Apr 7, 2011
    #15
  16. Roedy Green <> wrote:
    > On 06 Apr 2011 20:48:41 GMT, Andreas Leitgeb
    ><> wrote, quoted or indirectly quoted
    > someone who said :
    >
    >> Is there any *good* use of having the constructor call a method
    >> that actually *can* be overridden in a subclass?

    >
    > I have accidentally nailed myself by overriding a method used in a
    > constructor. I have yet to find a legitimate use for it. It is too
    > bad the compiler does not complain about it.


    I haven't (yet) been bitten by it, myself.
    I just recently came to think about it.
     
    Andreas Leitgeb, Apr 7, 2011
    #16
  17. Paul Cager <> wrote:
    >> (*): In German, we use double-quotes also to indicate tongue-in-cheek
    >> formulations that aren't to be taken entirely literally/serious.

    > I think we use the same convention in British English. I'm not certain
    > about our "colonial cousins".

    :)

    > The convention also spills over into spoken English, often using non-
    > verbal hints. There was also a fad at one time for people to raise
    > their hands to either side of their head and wriggle two fingers to
    > imitate quotes. I believe it's only used ironically now.


    Is that a consequence of the "Austin Powers" movies, or did the
    movies only make fun of an already common behavioural pattern?
     
    Andreas Leitgeb, Apr 7, 2011
    #17
  18. Tobias Blass <> wrote:
    >>> It's hard to prove that a constructor never calls a virtual method. Consider:
    >>> [ example of c'tor calling a private method "internalInit", which in turn
    >>> calls virtual "virtualMethod". ]

    >> Good point. The compiler couldn't (at least not statically) prevent
    >> indirect calling of overridable non-static methods.
    >>
    >> But otoh., it refuses to compile this:
    >> String bad = (String) new Integer(42);
    >> while allowing this: (sure bomb at runtime)
    >> String bad = (String) (Object) new Integer(42);


    > Why should it complain about your second example? You tell the Compiler
    > explicitly "Please consider this Integer as Object and this Object as String,


    It wasn't my intention to criticize that double-casts are allowed,
    nor that single casts of incompatible types aren't. Just, that there
    already is an example of something bad, that is indirectly possible
    but directly forbidden.

    > I know types don't match but I know what I'm doing"


    Interestingly, those cases where such a double cast would
    solve a real problem (namely casting between two interfaces
    or between a non-final class and an interface & vice versa)
    do already work with a single cast, so I don't really understand,
    what double casts are really good for.

    > (I'm programming in C at the moment where the Compiler doesn't
    > complain about things javac wouldn't even compile as in your
    > first example, so YMMV)


    Casting in C++ is something different than in Java.
    Although, if you really do C, not C++, then it's it's
    much more like Java, except for the lacking safety net.

    I'm doing C++, and recently I noticed a mistake of mine on
    rereading it: I had tried to use polymorphism with objects
    stored directly in an stl vector<baseclass>... ;-)
    Changed it to vector<const baseclass*>, a few "."s to "->"s, and
    added a few "new"s, allowing me to continue using polymorphism.
    (The vector isn't meant to ever shrink till end of process, so no
    extra "delete"s. Also, it only grows during initialization.)
     
    Andreas Leitgeb, Apr 7, 2011
    #18
  19. Lew <> wrote:
    > On 04/07/2011 04:44 AM, Andreas Leitgeb wrote:
    >> Lew<> wrote:
    >>> Andreas Leitgeb wrote:
    >>>>> Is there any *good* use of having the constructor call a method that
    >>>>> actually *can* be overridden in a subclass? I mean, are there
    >>>>> (non-anti)patterns of explicitly allowing subclasses to hook into
    >>>>> base-class's construction?
    >>> private final Logger logger = getLogger( getClass() );

    >> I thought, I made it clear, that calling static methods was not relevant
    >> to my question. So, kind of thanks for pointing out that I should have
    >> written non-static in the very line of the question, rather than consider
    >> that clear from the other (snipped by you) paragraphs of my post...

    >
    > I did not realize that 'getClass()' was static.


    I did not realize that getClass() was overidable - a property I even
    explicitly repeated in my question. For this, I assumed you were
    talking of getLogger().
     
    Andreas Leitgeb, Apr 7, 2011
    #19
  20. Robert Klemme <> wrote:
    > On 7 Apr., 10:44, Andreas Leitgeb <>
    > wrote:
    >> Lew <> wrote:
    >> > Andreas Leitgeb wrote:
    >> >>> Is there any *good* use of having the constructor call a method that
    >> >>> actually *can* be overridden in a subclass? I mean, are there
    >> >>> (non-anti)patterns of explicitly allowing subclasses to hook into
    >> >>> base-class's construction?

    >>
    >> > import org.apache.log4j.Logger;
    >> > import static org.apache.log4j.getLogger;
    >> > public class Foo
    >> > {
    >> >     private final Logger logger = getLogger( getClass() );
    >> >   // ...
    >> > }

    >>
    >> I thought, I made it clear, that calling static methods was not relevant
    >> to my question.  So, kind of thanks for pointing out that I should have
    >> written non-static in the very line of the question, rather than consider
    >> that clear from the other (snipped by you) paragraphs of my post...

    >
    > Well, that is clear, but: getClass() isn't a static method.


    Because getClass() is final, it didn't occur to me, that he
    would have put up *that* as an example...

    > As for me, I can't remember having shot myself in the foot with this
    > feature of Java (i.e. allowing to invoke virtual methods in
    > constructor). I reckon, language designers figured that allowing it
    > is more worthwhile than preventing it. As Thomas pointed out you
    > would have to provide constructor arguments so subclasses can pass on
    > data they have created. This is tiresome and may even end up being
    > inefficient namely in the case where the superclass constructor needs
    > to decide which methods to call (or whether methods to call). You
    > would end up creating objects which then need to be discarded if the
    > super class constructor decides that he does not need them =>
    > inefficient code.


    The example of that Library class-hierarchy looked a bit
    contrived to me.

    > Btw, the check would be expensive for the compiler and I am also not
    > sure how that byte code might look like because you need to extend the
    > restrictions to all methods. [...]


    It would be already an improvement, if direct calls to such
    methods from the constructor were forbidden.
     
    Andreas Leitgeb, Apr 7, 2011
    #20
    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. EdUarDo
    Replies:
    4
    Views:
    22,678
    Roedy Green
    Dec 21, 2005
  2. Oliver Wong
    Replies:
    14
    Views:
    1,628
    Chris Uppal
    Jun 13, 2006
  3. Generic Usenet Account
    Replies:
    10
    Views:
    2,245
  4. avasilev
    Replies:
    23
    Views:
    695
    avasilev
    Dec 9, 2011
  5. NetManiac
    Replies:
    1
    Views:
    145
    Morton Goldberg
    Aug 21, 2007
Loading...

Share This Page