Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.java.programmer > #2904 > unrolled thread
| Started by | Andreas Leitgeb <avl@gamma.logic.tuwien.ac.at> |
|---|---|
| First post | 2011-04-06 20:48 +0000 |
| Last post | 2011-04-08 20:02 +0200 |
| Articles | 20 on this page of 51 — 15 participants |
Back to article view | Back to comp.lang.java.programmer
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 →
| From | Andreas Leitgeb <avl@gamma.logic.tuwien.ac.at> |
|---|---|
| Date | 2011-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]
| From | Arved Sandstrom <asandstrom3minus1@eastlink.ca> |
|---|---|
| Date | 2011-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]
| From | Andreas Leitgeb <avl@gamma.logic.tuwien.ac.at> |
|---|---|
| Date | 2011-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]
| From | Paul Cager <paul.cager@googlemail.com> |
|---|---|
| Date | 2011-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]
| From | Andreas Leitgeb <avl@gamma.logic.tuwien.ac.at> |
|---|---|
| Date | 2011-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]
| From | Owen Jacobson <angrybaldguy@gmail.com> |
|---|---|
| Date | 2011-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]
| From | Andreas Leitgeb <avl@gamma.logic.tuwien.ac.at> |
|---|---|
| Date | 2011-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]
| From | Tobias Blass <tobiasblass@gmx.net> |
|---|---|
| Date | 2011-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]
| From | Andreas Leitgeb <avl@gamma.logic.tuwien.ac.at> |
|---|---|
| Date | 2011-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]
| From | Alessio Stalla <alessiostalla@gmail.com> |
|---|---|
| Date | 2011-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]
| From | Tobias Blass <tobiasblass@gmx.net> |
|---|---|
| Date | 2011-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]
| From | Andreas Leitgeb <avl@gamma.logic.tuwien.ac.at> |
|---|---|
| Date | 2011-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]
| From | Jim Janney <jjanney@shell.xmission.com> |
|---|---|
| Date | 2011-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]
| From | Eric Sosman <esosman@ieee-dot-org.invalid> |
|---|---|
| Date | 2011-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]
| From | Jim Janney <jjanney@shell.xmission.com> |
|---|---|
| Date | 2011-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]
| From | Andreas Leitgeb <avl@gamma.logic.tuwien.ac.at> |
|---|---|
| Date | 2011-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]
| From | Lew <lew@lewscanon.com> |
|---|---|
| Date | 2011-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]
| From | Jim Janney <jjanney@shell.xmission.com> |
|---|---|
| Date | 2011-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]
| From | Lew <noone@lewscanon.com> |
|---|---|
| Date | 2011-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]
| From | Owen Jacobson <angrybaldguy@gmail.com> |
|---|---|
| Date | 2011-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