Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #2904 > unrolled thread

calling own methods from constructor

Started byAndreas Leitgeb <avl@gamma.logic.tuwien.ac.at>
First post2011-04-06 20:48 +0000
Last post2011-04-08 20:02 +0200
Articles 20 on this page of 51 — 15 participants

Back to article view | Back to comp.lang.java.programmer


Contents

  calling own methods from constructor Andreas Leitgeb <avl@gamma.logic.tuwien.ac.at> - 2011-04-06 20:48 +0000
    Re: calling own methods from constructor Tom Anderson <twic@urchin.earth.li> - 2011-04-06 23:06 +0100
      Re: calling own methods from constructor Lew <noone@lewscanon.com> - 2011-04-06 18:24 -0400
        Re: calling own methods from constructor Andreas Leitgeb <avl@gamma.logic.tuwien.ac.at> - 2011-04-07 08:44 +0000
          Re: calling own methods from constructor Robert Klemme <shortcutter@googlemail.com> - 2011-04-07 04:14 -0700
            Re: calling own methods from constructor Andreas Leitgeb <avl@gamma.logic.tuwien.ac.at> - 2011-04-07 12:32 +0000
              Re: calling own methods from constructor Robert Klemme <shortcutter@googlemail.com> - 2011-04-07 05:55 -0700
              Re: calling own methods from constructor Lew <lew@lewscanon.com> - 2011-04-07 08:10 -0700
                Re: calling own methods from constructor Andreas Leitgeb <avl@gamma.logic.tuwien.ac.at> - 2011-04-07 20:31 +0000
                  Re: calling own methods from constructor Lew <lew@lewscanon.com> - 2011-04-07 14:10 -0700
                    Re: calling own methods from constructor Andreas Leitgeb <avl@gamma.logic.tuwien.ac.at> - 2011-04-07 22:15 +0000
                      Re: calling own methods from constructor Lew <noone@lewscanon.com> - 2011-04-07 21:22 -0400
                Re: calling own methods from constructor Tom Anderson <twic@urchin.earth.li> - 2011-04-07 23:08 +0100
                  Re: calling own methods from constructor Lew <noone@lewscanon.com> - 2011-04-07 21:24 -0400
                  Re: calling own methods from constructor "Mike Schilling" <mscottschilling@hotmail.com> - 2011-04-09 22:06 -0700
              Re: calling own methods from constructor Tom Anderson <twic@urchin.earth.li> - 2011-04-07 23:10 +0100
                Re: calling own methods from constructor Andreas Leitgeb <avl@gamma.logic.tuwien.ac.at> - 2011-04-07 22:24 +0000
          Re: calling own methods from constructor Lew <noone@lewscanon.com> - 2011-04-07 07:19 -0400
            Re: calling own methods from constructor Andreas Leitgeb <avl@gamma.logic.tuwien.ac.at> - 2011-04-07 12:24 +0000
      Re: calling own methods from constructor Eric Sosman <esosman@ieee-dot-org.invalid> - 2011-04-06 20:46 -0400
      Re: calling own methods from constructor Andreas Leitgeb <avl@gamma.logic.tuwien.ac.at> - 2011-04-07 08:36 +0000
        Re: calling own methods from constructor Arved Sandstrom <asandstrom3minus1@eastlink.ca> - 2011-04-07 07:16 -0300
          Re: calling own methods from constructor Andreas Leitgeb <avl@gamma.logic.tuwien.ac.at> - 2011-04-07 11:26 +0000
        Re: calling own methods from constructor Paul Cager <paul.cager@googlemail.com> - 2011-04-07 03:20 -0700
          Re: calling own methods from constructor Andreas Leitgeb <avl@gamma.logic.tuwien.ac.at> - 2011-04-07 11:36 +0000
    Re: calling own methods from constructor Owen Jacobson <angrybaldguy@gmail.com> - 2011-04-06 22:23 -0400
      Re: calling own methods from constructor Andreas Leitgeb <avl@gamma.logic.tuwien.ac.at> - 2011-04-07 09:13 +0000
        Re: calling own methods from constructor Tobias Blass <tobiasblass@gmx.net> - 2011-04-07 10:58 +0000
          Re: calling own methods from constructor Andreas Leitgeb <avl@gamma.logic.tuwien.ac.at> - 2011-04-07 12:19 +0000
            Re: calling own methods from constructor Alessio Stalla <alessiostalla@gmail.com> - 2011-04-07 10:40 -0700
              Re: calling own methods from constructor Tobias Blass <tobiasblass@gmx.net> - 2011-04-07 19:00 +0000
                Re: calling own methods from constructor Andreas Leitgeb <avl@gamma.logic.tuwien.ac.at> - 2011-04-07 20:11 +0000
                Re: calling own methods from constructor Jim Janney <jjanney@shell.xmission.com> - 2011-04-07 14:36 -0600
                Re: calling own methods from constructor Eric Sosman <esosman@ieee-dot-org.invalid> - 2011-04-07 20:59 -0400
      Re: calling own methods from constructor Jim Janney <jjanney@shell.xmission.com> - 2011-04-07 10:26 -0600
        Re: calling own methods from constructor Andreas Leitgeb <avl@gamma.logic.tuwien.ac.at> - 2011-04-07 20:16 +0000
        Re: calling own methods from constructor Lew <lew@lewscanon.com> - 2011-04-07 14:05 -0700
          Re: calling own methods from constructor Jim Janney <jjanney@shell.xmission.com> - 2011-04-07 16:15 -0600
            Re: calling own methods from constructor Lew <noone@lewscanon.com> - 2011-04-07 21:28 -0400
            Re: calling own methods from constructor Owen Jacobson <angrybaldguy@gmail.com> - 2011-04-07 23:21 -0400
              Re: calling own methods from constructor Owen Jacobson <angrybaldguy@gmail.com> - 2011-04-07 23:39 -0400
              Re: calling own methods from constructor Owen Jacobson <angrybaldguy@gmail.com> - 2011-04-07 23:58 -0400
              Re: calling own methods from constructor Tom Anderson <twic@urchin.earth.li> - 2011-04-08 20:32 +0100
        Re: calling own methods from constructor Tom Anderson <twic@urchin.earth.li> - 2011-04-07 23:05 +0100
          Re: calling own methods from constructor Jim Janney <jjanney@shell.xmission.com> - 2011-04-07 17:38 -0600
    Re: calling own methods from constructor Roedy Green <see_website@mindprod.com.invalid> - 2011-04-07 03:20 -0700
      Re: calling own methods from constructor Andreas Leitgeb <avl@gamma.logic.tuwien.ac.at> - 2011-04-07 11:32 +0000
    Re: calling own methods from constructor Daniele Futtorovic <da.futt.news@laposte-dot-net.invalid> - 2011-04-08 01:51 +0200
      Re: calling own methods from constructor Daniele Futtorovic <da.futt.news@laposte-dot-net.invalid> - 2011-04-08 01:56 +0200
        Re: calling own methods from constructor Andreas Leitgeb <avl@gamma.logic.tuwien.ac.at> - 2011-04-08 09:30 +0000
          Re: calling own methods from constructor Daniele Futtorovic <da.futt.news@laposte-dot-net.invalid> - 2011-04-08 20:02 +0200

Page 1 of 3  [1] 2 3  Next page →


#2904 — calling own methods from constructor

FromAndreas Leitgeb <avl@gamma.logic.tuwien.ac.at>
Date2011-04-06 20:48 +0000
Subjectcalling own methods from constructor
Message-ID<slrnippkd9.phi.avl@gamma.logic.tuwien.ac.at>
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.

[toc] | [next] | [standalone]


#2906

FromTom Anderson <twic@urchin.earth.li>
Date2011-04-06 23:06 +0100
Message-ID<alpine.DEB.2.00.1104062255160.1512@urchin.earth.li>
In reply to#2904
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

[toc] | [prev] | [next] | [standalone]


#2907

FromLew <noone@lewscanon.com>
Date2011-04-06 18:24 -0400
Message-ID<inip6r$l2n$1@news.albasani.net>
In reply to#2906
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

[toc] | [prev] | [next] | [standalone]


#2916

FromAndreas Leitgeb <avl@gamma.logic.tuwien.ac.at>
Date2011-04-07 08:44 +0000
Message-ID<slrnipqubm.phi.avl@gamma.logic.tuwien.ac.at>
In reply to#2907
Lew <noone@lewscanon.com> 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...

[toc] | [prev] | [next] | [standalone]


#2923

FromRobert Klemme <shortcutter@googlemail.com>
Date2011-04-07 04:14 -0700
Message-ID<41ac2ca5-83e8-4b80-92af-9704b373ec37@q36g2000yqn.googlegroups.com>
In reply to#2916
On 7 Apr., 10:44, Andreas Leitgeb <a...@gamma.logic.tuwien.ac.at>
wrote:
> Lew <no...@lewscanon.com> 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

[toc] | [prev] | [next] | [standalone]


#2930

FromAndreas Leitgeb <avl@gamma.logic.tuwien.ac.at>
Date2011-04-07 12:32 +0000
Message-ID<slrniprbm5.phi.avl@gamma.logic.tuwien.ac.at>
In reply to#2923
Robert Klemme <shortcutter@googlemail.com> wrote:
> On 7 Apr., 10:44, Andreas Leitgeb <a...@gamma.logic.tuwien.ac.at>
> wrote:
>> Lew <no...@lewscanon.com> 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.

[toc] | [prev] | [next] | [standalone]


#2933

FromRobert Klemme <shortcutter@googlemail.com>
Date2011-04-07 05:55 -0700
Message-ID<13fe6a88-ce90-4a00-9801-50b1fad65251@d19g2000yql.googlegroups.com>
In reply to#2930
On 7 Apr., 14:32, Andreas Leitgeb <a...@gamma.logic.tuwien.ac.at>
wrote:
> Robert Klemme <shortcut...@googlemail.com> wrote:
> > On 7 Apr., 10:44, Andreas Leitgeb <a...@gamma.logic.tuwien.ac.at>
> > wrote:
> >> Lew <no...@lewscanon.com> 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...

Now there we have something *I* have overlooked. :-)  I thought he had
picked it because getClass() always returns the actual class of the
instance regardless from which constructor it is invoked (other than
in C++) - but yes, it's probably not the perfect 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.

I am not convinced.  The risk seems rather low compared to the efforts
needed to implement your rule and the fact that now suddenly we get an
inconsistency: direct calls are forbidden while indirect calls are
allowed.  Everybody needing this would instantaneously would start
swearing and a second later introduce a private method whose only
purpose is to delegate the call to the "forbidden" method.  No, I
don't think this is a good idea.  After all we are grown ups and
should take responsibility for the code we write.  How often did you
shoot yourself in the foot because you are allowed to invoke sub class
methods from a constructor?

Cheers

robert

[toc] | [prev] | [next] | [standalone]


#2935

FromLew <lew@lewscanon.com>
Date2011-04-07 08:10 -0700
Message-ID<304a8aef-3852-4817-b5a7-5468fcdf11a1@x18g2000yqe.googlegroups.com>
In reply to#2930
On Apr 7, 8:32 am, Andreas Leitgeb <a...@gamma.logic.tuwien.ac.at>
wrote:
> Robert Klemme <shortcut...@googlemail.com> wrote:
> > On 7 Apr., 10:44, Andreas Leitgeb <a...@gamma.logic.tuwien.ac.at>
> > wrote:
> >> Lew <no...@lewscanon.com> 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...
>

Boy, you're spoiling for a fight, ain't'cha, sport?

It's final but it always returns the runtime class, so it is
overridden by the individual subtypes under the hood by special
compiler magic.  Otherwise 'String#getClass()' would report type
'Object', which obviously it doesn't.

It presents the same kind of behavior as non-final overridable methods
for the purposes of this discussion.

You can use the same idiom using the "true Scotsman" definition of
overridability, just so we don't get sidetracked in a pointless
quibble.  Hm-kaay?

(uncompiled:)

 class Foo
 {
   private static final String FOOT = Foo.class.getSimpleName();
   public String getFoot()
   {
     return FOOT;
   }

   private final String represent = "Insert "+ getFoot();
   public String toString()
   {
     return represent;
   }
 }

 class Bar extends Foo
 {
   private static final String BART = Bar.class.getSimpleName();
   public String getFoot()
   {
     return BART;
   }
 }

--
Lew

[toc] | [prev] | [next] | [standalone]


#2943

FromAndreas Leitgeb <avl@gamma.logic.tuwien.ac.at>
Date2011-04-07 20:31 +0000
Message-ID<slrnips7ou.phi.avl@gamma.logic.tuwien.ac.at>
In reply to#2935
Lew <lew@lewscanon.com> wrote:
>> >> > Andreas Leitgeb wrote:
>> >> >>> Is there any *good* use of having the constructor call a method that
>> >> >>> actually *can* be overridden in a subclass? ...
>> >> > Foo() { [...] = [...] someStaticMethod ( getClass() ); [...] }
>> Because getClass() is final, it didn't occur to me, that he
>> would have put up *that* as an example...
> Boy, you're spoiling for a fight, ain't'cha, sport?
> It's final but it always returns the runtime class, so it is
> overridden by the individual subtypes under the hood by special
> compiler magic.

Actually, I tried to explain, why I was rambling about static methods
in response to your example.

Now, that you've made your point clearer, namely that getClass() 
behaves like a virtual method overridden for *every* class, I even
understand it.

I'm just not yet convinced that this particular pattern, which is already
handled by JVM-magic (rather than by the compiler synthesizing those
virtual methods), would say "it's good to be able to call overridable
non-static methods from a constructor" sufficiently loudly. ;-)

[toc] | [prev] | [next] | [standalone]


#2947

FromLew <lew@lewscanon.com>
Date2011-04-07 14:10 -0700
Message-ID<0b2e25ae-35d6-45b6-8b8f-ac24d90f59ec@v8g2000yqb.googlegroups.com>
In reply to#2943
Andreas Leitgeb wrote:
> Actually, I tried to explain, why I was rambling about static methods
> in response to your example.
>

No, you tried to be sarcastic and to make my answer seem wrong even
though it was precisely what you asked for.

> Now, that you've made your point clearer, namely that getClass()
> behaves like a virtual method overridden for *every* class, I even
> understand it.
>

And it even exactly fits the parameters of your original question.

> I'm just not yet convinced that this particular pattern, which is already
> handled by JVM-magic (rather than by the compiler synthesizing those
> virtual methods), would say "it's good to be able to call overridable
> non-static methods from a constructor" sufficiently loudly. ;-)

I didn't ever say that it was good in such a general sense, thank you
very much for shifting the context yet again.

You asked if there were specific cases where it was good to use an
overridable (you never said 'final' until you started pulling your "no
true Scotsman" routine) method.  I pointed out such.

"Loudness" was not part of your request.

It's just that there are occasionally (!) times when an overridable
method (though not necessarily a 'final' one, since even 'final'
methods can call overridable methods in turn) can be usefully called
inside a constructor (or initializer, equivalently).  That was the
parameter of the original question, and that has been demonstrated.

Twice over, now.

--
Lew

[toc] | [prev] | [next] | [standalone]


#2952

FromAndreas Leitgeb <avl@gamma.logic.tuwien.ac.at>
Date2011-04-07 22:15 +0000
Message-ID<slrnipsdr7.phi.avl@gamma.logic.tuwien.ac.at>
In reply to#2947
Lew <lew@lewscanon.com> wrote:
> Andreas Leitgeb wrote:
>> Actually, I tried to explain, why I was rambling about static methods
>> in response to your example.
> No, you tried to be sarcastic and to make my answer seem wrong even
> though it was precisely what you asked for.

Without the explanation that you only gave later, it *was* wrong.

I asked for an example of calling an overridable method from the
constructor, and you gave an example where both a static and a final
method got called. That that final method *could* have been instead
implemented as a bunch of virtual methods, definitely wasn't obvious
at that point.
If you provide cryptic answers, just don't be surprised about them
being misunderstood and therefore taken as non-answers. Until you
explain them, that is.

> You asked if there were specific cases where it was good to use an
> overridable (you never said 'final' [...])

But 'final' surely implies non-overridability, doesn't it?  Therefore,
overridability of a method implies its non-'final'ity.

> It's just that there are occasionally (!) times when an overridable
> method (though not necessarily a 'final' one, since even 'final'
> methods can call overridable methods in turn) can be usefully called
> inside a constructor (or initializer, equivalently).  That was the
> parameter of the original question, and that has been demonstrated.
> Twice over, now.
'kay

[toc] | [prev] | [next] | [standalone]


#2965

FromLew <noone@lewscanon.com>
Date2011-04-07 21:22 -0400
Message-ID<inlo0i$b9j$1@news.albasani.net>
In reply to#2952
Andreas Leitgeb wrote:
> Lew wrote:
>> You asked if there were specific cases where it was good to use an
>> overridable (you never said 'final' [...])

> But 'final' surely implies non-overridability, doesn't it?  Therefore,
> overridability of a method implies its non-'final'ity.

Something used by 'getClass()' is overridden somewhere inside.  Otherwise its 
behavior would not be what it is.  Therefore there's an overridable method 
being called somewhere in the example I gave.  Therefore it's a valid example. 
  Give it a rest.

First you wanted to excoriate the example for being 'static', which it wasn't. 
  Then you wanted to excoriate it because the outer method is 'final', which 
is irrelevant.  All along you had an example in front of you where it was 
useful to call an overridable method from a constructor, which is all that you 
asked for.  You didn't (originally) ask that the method be called through a 
non-'final' method call.  Instead you argued about points that had nothing to 
do with the example's validity or its utility.

When you did add the rule that the call be directly to a non-'final' method, I 
promptly showed the equivalent example adhering to that new rule.

What new rule are you going to add now, Mr. No True Scotsman?

-- 
Lew
Honi soit qui mal y pense.
http://upload.wikimedia.org/wikipedia/commons/c/cf/Friz.jpg

[toc] | [prev] | [next] | [standalone]


#2950

FromTom Anderson <twic@urchin.earth.li>
Date2011-04-07 23:08 +0100
Message-ID<alpine.DEB.2.00.1104072305290.25031@urchin.earth.li>
In reply to#2935

[Multipart message — attachments visible in raw view] — view raw

On Thu, 7 Apr 2011, Lew wrote:

> On Apr 7, 8:32 am, Andreas Leitgeb <a...@gamma.logic.tuwien.ac.at>
> wrote:
>
>> Because getClass() is final, it didn't occur to me, that he would have 
>> put up *that* as an example...
>
> Boy, you're spoiling for a fight, ain't'cha, sport?
>
> It's final but it always returns the runtime class, so it is overridden 
> by the individual subtypes under the hood by special compiler magic.

What? No.

> Otherwise 'String#getClass()' would report type 'Object', which 
> obviously it doesn't.

No. getClass() is final, not virtual, it is never overridden, and it does 
not behave like it has been overridden. Rather, it behaves like its 
implementation was:

public Class getClass() {
 	return this.class;
}

Where all objects have a secret magic hidden field called 'class' which is 
set by the VM when they are allocated.

> It presents the same kind of behavior as non-final overridable methods 
> for the purposes of this discussion.

It really doesn't. The problem with calling overridable methods from 
constructors is that they can be overridden with code which assumes a 
constructed object, and gets into trouble when run in the context of one 
which isn't. getClass() can't get into that kind of trouble.

tom

-- 
Many of us adopted the File's slang as our own, feeling that we'd found a
tangible sign of the community of minds we'd half-guessed to be out there.

[toc] | [prev] | [next] | [standalone]


#2966

FromLew <noone@lewscanon.com>
Date2011-04-07 21:24 -0400
Message-ID<inlo39$b85$1@news.albasani.net>
In reply to#2950
Tom Anderson wrote:
>> It presents the same kind of behavior as non-final overridable methods for
>> the purposes of this discussion.
>
> It really doesn't. The problem with calling overridable methods from
> constructors is that they can be overridden with code which assumes a
> constructed object, and gets into trouble when run in the context of one which
> isn't. getClass() can't get into that kind of trouble.

Fair enough.  Good points.

-- 
Lew
Honi soit qui mal y pense.
http://upload.wikimedia.org/wikipedia/commons/c/cf/Friz.jpg

[toc] | [prev] | [next] | [standalone]


#3017

From"Mike Schilling" <mscottschilling@hotmail.com>
Date2011-04-09 22:06 -0700
Message-ID<inrdsc$qdd$1@dont-email.me>
In reply to#2950

"Tom Anderson" <twic@urchin.earth.li> wrote in message 
news:alpine.DEB.2.00.1104072305290.25031@urchin.earth.li...
>
> No. getClass() is final, not virtual, it is never overridden, and it does
> not behave like it has been overridden. Rather, it behaves like its
> implementation was:
>
> public Class getClass() {
>  return this.class;
> }
>
> Where all objects have a secret magic hidden field called 'class' which is
> set by the VM when they are allocated.

That's how I've always thought about it, particularly since in 4GLs I've 
helped implement, that's exactly what the analogous method did. 

[toc] | [prev] | [next] | [standalone]


#2951

FromTom Anderson <twic@urchin.earth.li>
Date2011-04-07 23:10 +0100
Message-ID<alpine.DEB.2.00.1104072309110.25031@urchin.earth.li>
In reply to#2930
On Thu, 7 Apr 2011, Andreas Leitgeb wrote:

> Robert Klemme <shortcutter@googlemail.com> wrote:
>
>> 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.

It was entirely contrived. I will keep an eye out for real code which does 
this, but i thought a timely answer was desirable!

tom

-- 
Many of us adopted the File's slang as our own, feeling that we'd found a
tangible sign of the community of minds we'd half-guessed to be out there.

[toc] | [prev] | [next] | [standalone]


#2954

FromAndreas Leitgeb <avl@gamma.logic.tuwien.ac.at>
Date2011-04-07 22:24 +0000
Message-ID<slrnipsedn.phi.avl@gamma.logic.tuwien.ac.at>
In reply to#2951
Tom Anderson <twic@urchin.earth.li> wrote:
>> The example of that Library class-hierarchy looked a bit
>> contrived to me.
> It was entirely contrived.

:-)

> I will keep an eye out for real code which does 
> this,

I'd appreciate. 

> but i thought a timely answer was desirable!

appreciated in hindsight :)

[toc] | [prev] | [next] | [standalone]


#2924

FromLew <noone@lewscanon.com>
Date2011-04-07 07:19 -0400
Message-ID<ink6j5$28p$1@news.albasani.net>
In reply to#2916
On 04/07/2011 04:44 AM, Andreas Leitgeb wrote:
> Lew<noone@lewscanon.com>  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

[toc] | [prev] | [next] | [standalone]


#2929

FromAndreas Leitgeb <avl@gamma.logic.tuwien.ac.at>
Date2011-04-07 12:24 +0000
Message-ID<slrniprb7s.phi.avl@gamma.logic.tuwien.ac.at>
In reply to#2924
Lew <noone@lewscanon.com> wrote:
> On 04/07/2011 04:44 AM, Andreas Leitgeb wrote:
>> Lew<noone@lewscanon.com>  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().

[toc] | [prev] | [next] | [standalone]


#2908

FromEric Sosman <esosman@ieee-dot-org.invalid>
Date2011-04-06 20:46 -0400
Message-ID<inj1mf$nu2$1@dont-email.me>
In reply to#2906
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
esosman@ieee-dot-org.invalid

[toc] | [prev] | [next] | [standalone]


Page 1 of 3  [1] 2 3  Next page →

Back to top | Article view | comp.lang.java.programmer


csiph-web