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 2 of 3 — ← Prev page 1 [2] 3  Next page →


#2915

FromAndreas Leitgeb <avl@gamma.logic.tuwien.ac.at>
Date2011-04-07 08:36 +0000
Message-ID<slrnipqtt1.phi.avl@gamma.logic.tuwien.ac.at>
In reply to#2906
Tom Anderson <twic@urchin.earth.li> 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?

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


#2919

FromArved Sandstrom <asandstrom3minus1@eastlink.ca>
Date2011-04-07 07:16 -0300
Message-ID<Y9gnp.8360$zn.1780@newsfe19.iad>
In reply to#2915
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

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


#2925

FromAndreas Leitgeb <avl@gamma.logic.tuwien.ac.at>
Date2011-04-07 11:26 +0000
Message-ID<slrnipr7r3.phi.avl@gamma.logic.tuwien.ac.at>
In reply to#2919
Arved Sandstrom <asandstrom3minus1@eastlink.ca> 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.

:/

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


#2921

FromPaul Cager <paul.cager@googlemail.com>
Date2011-04-07 03:20 -0700
Message-ID<1620d07e-07bf-4ccf-864b-653575e9e887@cu4g2000vbb.googlegroups.com>
In reply to#2915
On Apr 7, 9:36 am, Andreas Leitgeb <a...@gamma.logic.tuwien.ac.at>
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.

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


#2927

FromAndreas Leitgeb <avl@gamma.logic.tuwien.ac.at>
Date2011-04-07 11:36 +0000
Message-ID<slrnipr8dg.phi.avl@gamma.logic.tuwien.ac.at>
In reply to#2921
Paul Cager <paul.cager@googlemail.com> 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?

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


#2909

FromOwen Jacobson <angrybaldguy@gmail.com>
Date2011-04-06 22:23 -0400
Message-ID<2011040622233261380-angrybaldguy@gmailcom>
In reply to#2904
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

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


#2917

FromAndreas Leitgeb <avl@gamma.logic.tuwien.ac.at>
Date2011-04-07 09:13 +0000
Message-ID<slrnipr02k.phi.avl@gamma.logic.tuwien.ac.at>
In reply to#2909
Owen Jacobson <angrybaldguy@gmail.com> 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.

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


#2922

FromTobias Blass <tobiasblass@gmx.net>
Date2011-04-07 10:58 +0000
Message-ID<ink5cn$e78$1@dont-email.me>
In reply to#2917
On 2011-04-07, Andreas Leitgeb <avl@gamma.logic.tuwien.ac.at> wrote:
> Owen Jacobson <angrybaldguy@gmail.com> 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)

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


#2928

FromAndreas Leitgeb <avl@gamma.logic.tuwien.ac.at>
Date2011-04-07 12:19 +0000
Message-ID<slrniprauh.phi.avl@gamma.logic.tuwien.ac.at>
In reply to#2922
Tobias Blass <tobiasblass@gmx.net> 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.)

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


#2939

FromAlessio Stalla <alessiostalla@gmail.com>
Date2011-04-07 10:40 -0700
Message-ID<455e7ffb-369e-4d88-912e-01581c7cbfb5@bl1g2000vbb.googlegroups.com>
In reply to#2928
On 7 Apr, 14:19, Andreas Leitgeb <a...@gamma.logic.tuwien.ac.at>
wrote:
> 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 don't know about C++, but in C casting is not like Java at all. In
Java a cast is a runtime operation that checks the type of some object
(I'm not considering primitives). Of course the compiler knows about
it and uses it at compile-time too for type checking, but that's
somewhat a consequence of the previous point. In C, instead, casting
has no(*) runtime behavior; it's just an instruction for the compiler:
"please consider this datum to be of this type". If the compiler
accepts your order, it will blindly treat that datum as if it's of the
type you told it is, even if at runtime it's not.

(*) actually, it might perform conversions in certain corner cases,
but still no runtime type check is ever done.

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


#2940

FromTobias Blass <tobiasblass@gmx.net>
Date2011-04-07 19:00 +0000
Message-ID<inl1ku$6ht$1@dont-email.me>
In reply to#2939
On 2011-04-07, Alessio Stalla <alessiostalla@gmail.com> wrote:
> On 7 Apr, 14:19, Andreas Leitgeb <a...@gamma.logic.tuwien.ac.at>
> wrote:
>> 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 don't know about C++, but in C casting is not like Java at all. In
> Java a cast is a runtime operation that checks the type of some object
> (I'm not considering primitives). Of course the compiler knows about
> it and uses it at compile-time too for type checking, but that's
> somewhat a consequence of the previous point. In C, instead, casting
> has no(*) runtime behavior; it's just an instruction for the compiler:
> "please consider this datum to be of this type". If the compiler
> accepts your order, it will blindly treat that datum as if it's of the
> type you told it is, even if at runtime it's not.
>
> (*) actually, it might perform conversions in certain corner cases,
> but still no runtime type check is ever done.
Is there any case where the C compiler rejects casts? I cannot imagine an
example.

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


#2941

FromAndreas Leitgeb <avl@gamma.logic.tuwien.ac.at>
Date2011-04-07 20:11 +0000
Message-ID<slrnips6jq.phi.avl@gamma.logic.tuwien.ac.at>
In reply to#2940
Tobias Blass <tobiasblass@gmx.net> wrote:
> On 2011-04-07, Alessio Stalla <alessiostalla@gmail.com> wrote:
>> On 7 Apr, 14:19, Andreas Leitgeb <a...@gamma.logic.tuwien.ac.at> wrote:
>>> 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 don't know about C++, but in C casting is not like Java at all.

I dare to disagree, but this group here is not the place to elaborate
on it.  In a nutshell: C++ casts are just so much more unlike Java's ...

> Is there any case where the C compiler rejects casts? I cannot imagine an
> example.

Most likely it will reject casts between different structures or between
structures and primitives. (too lazy to test this now, though)

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


#2945

FromJim Janney <jjanney@shell.xmission.com>
Date2011-04-07 14:36 -0600
Message-ID<2ppqoxg5o8.fsf@shell.xmission.com>
In reply to#2940
Tobias Blass <tobiasblass@gmx.net> writes:

> On 2011-04-07, Alessio Stalla <alessiostalla@gmail.com> wrote:
>> On 7 Apr, 14:19, Andreas Leitgeb <a...@gamma.logic.tuwien.ac.at>
>> wrote:
>>> 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 don't know about C++, but in C casting is not like Java at all. In
>> Java a cast is a runtime operation that checks the type of some object
>> (I'm not considering primitives). Of course the compiler knows about
>> it and uses it at compile-time too for type checking, but that's
>> somewhat a consequence of the previous point. In C, instead, casting
>> has no(*) runtime behavior; it's just an instruction for the compiler:
>> "please consider this datum to be of this type". If the compiler
>> accepts your order, it will blindly treat that datum as if it's of the
>> type you told it is, even if at runtime it's not.
>>
>> (*) actually, it might perform conversions in certain corner cases,
>> but still no runtime type check is ever done.

Casts are routinely used to force conversions where needed:

#include <stdio.h>

int main() {
  int i = 17;
  printf("%f\n", (double) i);
  return 0;
}

> Is there any case where the C compiler rejects casts? I cannot imagine an
> example.

  struct {
    char* s;
    double d;
  } st;

  int i = (int) st; /* error: aggregate value used where an integer was expected */

-- 
Jim Janney

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


#2962

FromEric Sosman <esosman@ieee-dot-org.invalid>
Date2011-04-07 20:59 -0400
Message-ID<inlmlu$2he$1@dont-email.me>
In reply to#2940
On 4/7/2011 3:00 PM, Tobias Blass wrote:
> On 2011-04-07, Alessio Stalla<alessiostalla@gmail.com>  wrote:
>> On 7 Apr, 14:19, Andreas Leitgeb<a...@gamma.logic.tuwien.ac.at>
>> wrote:
>>> 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 don't know about C++, but in C casting is not like Java at all. In
>> Java a cast is a runtime operation that checks the type of some object
>> (I'm not considering primitives). Of course the compiler knows about
>> it and uses it at compile-time too for type checking, but that's
>> somewhat a consequence of the previous point. In C, instead, casting
>> has no(*) runtime behavior; it's just an instruction for the compiler:
>> "please consider this datum to be of this type". If the compiler
>> accepts your order, it will blindly treat that datum as if it's of the
>> type you told it is, even if at runtime it's not.
>>
>> (*) actually, it might perform conversions in certain corner cases,
>> but still no runtime type check is ever done.
> Is there any case where the C compiler rejects casts? I cannot imagine an
> example.

     (struct tm)42;

-- 
Eric Sosman
esosman@ieee-dot-org.invalid

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


#2937

FromJim Janney <jjanney@shell.xmission.com>
Date2011-04-07 10:26 -0600
Message-ID<2pzko2f2nx.fsf@shell.xmission.com>
In reply to#2909
Owen Jacobson <angrybaldguy@gmail.com> writes:

> 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.

public class Bar extends Foo {
    public Bar() {
        super();
        System.out.println("Two guys walk into a...");
    }

    @override
    public void virtualMethod() {
        throw new Exception("the bar is closed");
    }
}

In Java evaluating new Bar() will throw an exception.  But in C++ the
equivalent code would print

Override me! I dare you.
Two guys walk into a...

In effect, until the constructor of Foo completes, the object is
considered to be an instance of Foo, so calls to virtualMethod() to to
Foo.virtualMethod even if it has been overridden.  After the super
constructor completes, the object is treated as an instance of Bar, so
evaluating new Bar().virtualMethod() would print two lines and then
throw an exception.

I've been surprised by this behaviour in C++ enough times that I'm not
sure that it has the better approach.  But a solution does exist.

-- 
Jim Janney

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


#2942

FromAndreas Leitgeb <avl@gamma.logic.tuwien.ac.at>
Date2011-04-07 20:16 +0000
Message-ID<slrnips6t6.phi.avl@gamma.logic.tuwien.ac.at>
In reply to#2937
Jim Janney <jjanney@shell.xmission.com> wrote:
> In Java evaluating new Bar() will throw an exception.  But in C++ the
> equivalent code would print
> Override me! I dare you.
> Two guys walk into a...

I think, C++'s semantics are *better* for this case, but probably at
a price, that made it reasonable for Java to find a different tradeoff.

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


#2946

FromLew <lew@lewscanon.com>
Date2011-04-07 14:05 -0700
Message-ID<ce5128fc-f160-41f9-846a-71b1646dad33@hd10g2000vbb.googlegroups.com>
In reply to#2937
Janney wrote:
> In Java evaluating new Bar() will throw an exception.  But in C++ the
> equivalent code would print
>
> Override me! I dare you.
> Two guys walk into a...
>
> In effect, until the constructor of Foo completes, the object is
> considered to be an instance of Foo, so calls to virtualMethod() to to
> Foo.virtualMethod even if it has been overridden.  After the super
> constructor completes, the object is treated as an instance of Bar, so
> evaluating new Bar().virtualMethod() would print two lines and then
> throw an exception.
>
> I've been surprised by this behaviour in C++ enough times that I'm not
> sure that it has the better approach.  But a solution does exist.
>

A solution to what, exactly?

I ask because it sort of sounds like you're saying that C++ is a
solution to something in Java.  I don't guess that's what you're
really saying, of course, but it leaves me wondering what that is.
What is the problem that you aver exists, and what is its solution to
it that you aver exists?

--
Lew

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


#2953

FromJim Janney <jjanney@shell.xmission.com>
Date2011-04-07 16:15 -0600
Message-ID<2pwrj56744.fsf@shell.xmission.com>
In reply to#2946
Lew <lew@lewscanon.com> writes:

> Janney wrote:
>> In Java evaluating new Bar() will throw an exception.  But in C++ the
>> equivalent code would print
>>
>> Override me! I dare you.
>> Two guys walk into a...
>>
>> In effect, until the constructor of Foo completes, the object is
>> considered to be an instance of Foo, so calls to virtualMethod() to to
>> Foo.virtualMethod even if it has been overridden.  After the super
>> constructor completes, the object is treated as an instance of Bar, so
>> evaluating new Bar().virtualMethod() would print two lines and then
>> throw an exception.
>>
>> I've been surprised by this behaviour in C++ enough times that I'm not
>> sure that it has the better approach.  But a solution does exist.
>>
>
> A solution to what, exactly?

In the message I was replying to, in the text that you deleted, Owen
Jacobsen correctly observed that

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

This is a technical issue, and I observed that other languages have
found ways to prevent virtual methods from being called before their
owning objects have been fully constructed.  One can debate whether this
desirable, but C++ provides an existence proof that it's possible.

> I ask because it sort of sounds like you're saying that C++ is a
> solution to something in Java.  I don't guess that's what you're
> really saying, of course, but it leaves me wondering what that is.
> What is the problem that you aver exists, and what is its solution to
> it that you aver exists?

Consider focussing on what I did say, instead of what it sort of sounds
like I might have said.  The solution is in the paragraph above, the one
that starts with "In effect, until the constructor of Foo completes".

-- 
Jim Janney

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


#2968

FromLew <noone@lewscanon.com>
Date2011-04-07 21:28 -0400
Message-ID<inloam$bnl$1@news.albasani.net>
In reply to#2953
Jim Janney wrote:
> Lew writes:
> Consider focussing on what I did say, instead of what it sort of sounds
> like I might have said.  The solution is in the paragraph above, the one
> that starts with "In effect, until the constructor of Foo completes".

Dude, I was just asking for explanation of something I admitted I did not 
understand, and gave you what I admitted I understood to be a misimpression 
already.  I didn't quote everything you said because I naturally assumed you 
knew what you'd said and would understand if I have just enough context to 
establish my question.  I guess not.

Sah-ree!

-- 
Lew
Buh-bye, now.

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


#2971

FromOwen Jacobson <angrybaldguy@gmail.com>
Date2011-04-07 23:21 -0400
Message-ID<2011040723213981856-angrybaldguy@gmailcom>
In reply to#2953
On 2011-04-07 18:15:23 -0400, Jim Janney said:

> Lew <lew@lewscanon.com> writes:
> 
>> Janney wrote:
>>> In Java evaluating new Bar() will throw an exception.  But in C++ the
>>> equivalent code would print
>>> 
>>> Override me! I dare you.
>>> Two guys walk into a...
>>> 
>>> In effect, until the constructor of Foo completes, the object is
>>> considered to be an instance of Foo, so calls to virtualMethod() to to
>>> Foo.virtualMethod even if it has been overridden.  After the super
>>> constructor completes, the object is treated as an instance of Bar, so
>>> evaluating new Bar().virtualMethod() would print two lines and then
>>> throw an exception.
>>> 
>>> I've been surprised by this behaviour in C++ enough times that I'm not
>>> sure that it has the better approach.  But a solution does exist.
>>> 
>> 
>> A solution to what, exactly?

Lew, bog off.

> In the message I was replying to, in the text that you deleted, Owen
> Jacobsen correctly observed that

Jacobson. Like the UML guy, to my eternal mortification. :)

>>>> It's hard to prove that a constructor never calls a virtual method. Consider:
> 
> This is a technical issue, and I observed that other languages have
> found ways to prevent virtual methods from being called before their
> owning objects have been fully constructed.  One can debate whether this
> desirable, but C++ provides an existence proof that it's possible.

Sure. C++'s objection initialization proceeds from the top down, just 
like Java's, with the difference that the class of '*this' changes as 
constructors complete. In your extension of my example, with

	public class Foo { /* ... */ }

	public class Bar extends Foo { /* ... */ }

this would mean that during Foo's constructor, 'this' points to a Foo 
object, while during Bar's constructor, it points to a Bar object*. 
However, in Java, constructor chaining is syntactically a statement, so 
it appears that control flow begins in the most-derived class's 
constructor before chaining upwards through each superclass's 
constructor to Object() -- and that's exactly what happens under the 
hood!

	$ cat Surprise.java
	class Surprise {
	    public Surprise(String s) {
	        super(); // explicit for the sake of discussion only.
	    }
	}
	
	class Subprise extends Surprise {
	    public Subprise() {
	        super("Hello, world!");
	    }
	}
	
	$ javap -classpath . Subprise -c
	Compiled from "Surprise.java"
	class Subprise extends Surprise{
	public Subprise();
	  Code:
	   0:	aload_0
	   1:	ldc	#1; //String Hello, world!
	   3:	invokespecial	#2; //Method Surprise."<init>":(Ljava/lang/String;)V
	   6:	return
	
	}

Given that JVM-level implementation of constructors, having the class 
of 'this' change after the third instruction would be very tricky to 
implement. C++ doesn't have this problem, since (a) constructor 
chaining is NOT syntactically like a statement and (b) constructor 
chaining doesn't have to compile like one, either.

Could it have been designed differently? Sure. Java's constructor 
semantics are a weird-but-mostly-intuitive mix of C++'s constructors 
and Smalltalk's initializers-are-just-methods approach (where you're 
not forced to chain to a parent class's initializer at all). It's a 
compromise, and like all compromises, it's not quite like any of the 
alternatives; however, I think having the type of 'this' remain stable 
is a useful feature. :)

-o

* And also that if Foo.Foo() captures 'this' in a field, Bar.Bar() can 
compare this to the field using == and get true back, even though the 
class has changed. 'new' is only allowed to introduce one distinct new 
pointer.

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


Page 2 of 3 — ← Prev page 1 [2] 3  Next page →

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


csiph-web