Contructor bad practices----WAS: Re: Can someone use invokeLater()...  
Author Message
Thomas G. Marshall





PostPosted: 2004-10-25 0:33:00 Top

java-programmer, Contructor bad practices----WAS: Re: Can someone use invokeLater()... Alex Hunsley coughed up:

...[rip]...

>> Overly strict. I cannot /count/ the number of times I've seen
>> horribly convoluted code set out to avoid putting nearly /anything/
>> into a constructor.
>
> "Constructors should *not* call non-final or
> non-private methods" is not overly strict

STOP RIGHT THERE.

You meant: should *not* call non-final or non-private methods of that same
object? Sorry, I misunderstood your intent.

Then I totally agree.

Here's something else I see *all the time*: (pseudo-java, ignore scoping
rules):

class A
{
A() { helper(); }

helper() {....};
}

class B extends A
{
helper() {....}; // dangerous: overridden
}


...[rip]...

--
Framsticks. 3D Artificial Life evolution. You can see the creatures
that evolve and how they interact, hunt, swim, etc. (Unaffiliated with
me). http://www.frams.alife.pl/


 
Alex Hunsley





PostPosted: 2004-10-27 2:35:00 Top

java-programmer >> Contructor bad practices----WAS: Re: Can someone use invokeLater()... Thomas G. Marshall wrote:
> Alex Hunsley coughed up:
>
> ...[rip]...
>
>
>>>Overly strict. I cannot /count/ the number of times I've seen
>>>horribly convoluted code set out to avoid putting nearly /anything/
>>>into a constructor.
>>
>>"Constructors should *not* call non-final or
>>non-private methods" is not overly strict
>
>
> STOP RIGHT THERE.

Please don't shout, it's considered rude.

> You meant: should *not* call non-final or non-private methods of that same
> object? Sorry, I misunderstood your intent.

well, if I didn't mean that, then I would be talking about calling
private methods of *other classes* which wouldn't make any sense. So
yes, I meant of that same object, sorry if I wasn't clear on that.

> Then I totally agree.
>
> Here's something else I see *all the time*: (pseudo-java, ignore scoping
> rules):
>
> class A
> {
> A() { helper(); }
>
> helper() {....};
> }
>
> class B extends A
> {
> helper() {....}; // dangerous: overridden
> }

Yup, I see that too. I see dead people.
 
xarax





PostPosted: 2004-10-27 3:27:00 Top

java-programmer >> Contructor bad practices----WAS: Re: Can someone use invokeLater()... "Alex Hunsley" <email***@***.com> wrote in message
news:7Nwfd.159509$email***@***.com...
> Thomas G. Marshall wrote:
> > Alex Hunsley coughed up:
> >
> > ...[rip]...
> >
> >
> >>>Overly strict. I cannot /count/ the number of times I've seen
> >>>horribly convoluted code set out to avoid putting nearly /anything/
> >>>into a constructor.
> >>
> >>"Constructors should *not* call non-final or
> >>non-private methods" is not overly strict
> >
> >
> > STOP RIGHT THERE.
>
> Please don't shout, it's considered rude.
>
> > You meant: should *not* call non-final or non-private methods of that same
> > object? Sorry, I misunderstood your intent.
>
> well, if I didn't mean that, then I would be talking about calling
> private methods of *other classes* which wouldn't make any sense. So
> yes, I meant of that same object, sorry if I wasn't clear on that.
>
> > Then I totally agree.
> >
> > Here's something else I see *all the time*: (pseudo-java, ignore scoping
> > rules):
> >
> > class A
> > {
> > A() { helper(); }
> >
> > helper() {....};
> > }
> >
> > class B extends A
> > {
> > helper() {....}; // dangerous: overridden
> > }
>
> Yup, I see that too. I see dead people.

Yes, that can be dangerous when the subclass
doesn't properly handle the set-up that the
original helper() is supposed to do.

OTOH, I've seen things like this:

public class A
{
private final List myList;

protected abstract List init();

protected A()
{
myList = init();
}
}

public final class B
extends A
{
protected List init()
{
List result;

result = /* Create and initialize the List */;
return result;
}
}

The c'tor for class A is designed to call
method init() that is implemented by a subclass.
This is a good design, because there is no
"default" version of init() to override.
The subclass must fulfill its implied contract
with the parent class, and it must be careful
not to reference any subclass elements that
have not yet been initialized (because the
parent is still constructing). The init()
method must be completing self-contained with
no dependencies on the subclass instance.



 
 
Thomas G. Marshall





PostPosted: 2004-10-27 7:37:00 Top

java-programmer >> Contructor bad practices----WAS: Re: Can someone use invokeLater()... xarax coughed up:
> "Alex Hunsley" <email***@***.com> wrote in message
> news:7Nwfd.159509$email***@***.com...
>> Thomas G. Marshall wrote:
>>> Alex Hunsley coughed up:
>>>
>>> ...[rip]...
>>>
>>>
>>>>> Overly strict. I cannot /count/ the number of times I've seen
>>>>> horribly convoluted code set out to avoid putting nearly
>>>>> /anything/ into a constructor.
>>>>
>>>> "Constructors should *not* call non-final or
>>>> non-private methods" is not overly strict
>>>
>>>
>>> STOP RIGHT THERE.
>>
>> Please don't shout, it's considered rude.
>>
>>> You meant: should *not* call non-final or non-private methods of
>>> that same object? Sorry, I misunderstood your intent.
>>
>> well, if I didn't mean that, then I would be talking about calling
>> private methods of *other classes* which wouldn't make any sense. So
>> yes, I meant of that same object, sorry if I wasn't clear on that.
>>
>>> Then I totally agree.
>>>
>>> Here's something else I see *all the time*: (pseudo-java, ignore
>>> scoping rules):
>>>
>>> class A
>>> {
>>> A() { helper(); }
>>>
>>> helper() {....};
>>> }
>>>
>>> class B extends A
>>> {
>>> helper() {....}; // dangerous: overridden
>>> }
>>
>> Yup, I see that too. I see dead people.
>
> Yes, that can be dangerous when the subclass
> doesn't properly handle the set-up that the
> original helper() is supposed to do.
>
> OTOH, I've seen things like this:
>
> public class A
> {
> private final List myList;
>
> protected abstract List init();
>
> protected A()
> {
> myList = init();
> }
> }
>
> public final class B
> extends A
> {
> protected List init()
> {
> List result;
>
> result = /* Create and initialize the List */;
> return result;
> }
> }
>
> The c'tor for class A is designed to call
> method init() that is implemented by a subclass.
> This is a good design, because there is no
> "default" version of init() to override.

Doesn't matter. Why? Because....



> The subclass must fulfill its implied contract
> with the parent class, and it must be careful
> not to reference any subclass elements that
> have not yet been initialized

That. You're just asking for trouble.


> (because the
> parent is still constructing). The init()
> method must be completing self-contained with
> no dependencies on the subclass instance.



--
Framsticks. 3D Artificial Life evolution. You can see the creatures
that evolve and how they interact, hunt, swim, etc. (Unaffiliated with
me). http://www.frams.alife.pl/


 
 
Thomas G. Marshall





PostPosted: 2004-10-27 7:46:00 Top

java-programmer >> Contructor bad practices----WAS: Re: Can someone use invokeLater()... Alex Hunsley coughed up:
> Thomas G. Marshall wrote:
>> Alex Hunsley coughed up:
>>
>> ...[rip]...
>>
>>
>>>> Overly strict. I cannot /count/ the number of times I've seen
>>>> horribly convoluted code set out to avoid putting nearly /anything/
>>>> into a constructor.
>>>
>>> "Constructors should *not* call non-final or
>>> non-private methods" is not overly strict
>>
>>
>> STOP RIGHT THERE.
>
> Please don't shout, it's considered rude.
>
>> You meant: should *not* call non-final or non-private methods of
>> that same object? Sorry, I misunderstood your intent.
>
> well, if I didn't mean that, then I would be talking about calling
> private methods of *other classes* which wouldn't make any sense. So
> yes, I meant of that same object, sorry if I wasn't clear on that.

You were clear enough---I just wasn't paying /quite/ enough attention.


>
>> Then I totally agree.

I should not have said "totally" here either. More like "almost always".
But again, even in this case I recognize how truly heroic attempts at making
pure code result in impossible to maintain ugly code, so my comment
regarding the weighing of costs stands.


>> Here's something else I see *all the time*: (pseudo-java, ignore
>> scoping rules):
>>
>> class A
>> {
>> A() { helper(); }
>>
>> helper() {....};
>> }
>>
>> class B extends A
>> {
>> helper() {....}; // dangerous: overridden
>> }
>
> Yup, I see that too. I see dead people.

...You may be seeing the people I've /killed/ for making this mistake.
Tell'm to stop haunting me at night. Nobody needs to have ghosts chanting
"code nazi....code nazi..." all the time...



--
Framsticks. 3D Artificial Life evolution. You can see the creatures
that evolve and how they interact, hunt, swim, etc. (Unaffiliated with
me). http://www.frams.alife.pl/


 
 
Alex Hunsley





PostPosted: 2004-10-27 17:48:00 Top

java-programmer >> Contructor bad practices----WAS: Re: Can someone use invokeLater()... xarax wrote:
> "Alex Hunsley" <email***@***.com> wrote in message
> news:7Nwfd.159509$email***@***.com...
>
>>Yup, I see that too. I see dead people.
>
>
> Yes, that can be dangerous when the subclass
> doesn't properly handle the set-up that the
> original helper() is supposed to do.
>
> OTOH, I've seen things like this:
>
[snip example code]

> The c'tor for class A is designed to call
> method init() that is implemented by a subclass.
> This is a good design, because there is no
> "default" version of init() to override.

No, it's still a bad design.

> The subclass must fulfill its implied contract
> with the parent class, and it must be careful
> not to reference any subclass elements that
> have not yet been initialized (because the
> parent is still constructing). The init()
> method must be completing self-contained with
> no dependencies on the subclass instance.

Exactly. So you still have caveats, and someone else may not know about
them, or read about them, or you may forget about them yourself. To me
this is still just asking for trouble.
For me, the bottom line is: don't call non-final or non-private methods
of the same class from the constructor. Simple as that. Otherwise, you
just open yourself (and others who may edit your code) up for annoying
problems.




 
 
Alex Hunsley





PostPosted: 2004-10-27 18:02:00 Top

java-programmer >> Contructor bad practices----WAS: Re: Can someone use invokeLater()... Thomas G. Marshall wrote:
> Alex Hunsley coughed up:
>>well, if I didn't mean that, then I would be talking about calling
>>private methods of *other classes* which wouldn't make any sense. So
>>yes, I meant of that same object, sorry if I wasn't clear on that.
>
>
> You were clear enough---I just wasn't paying /quite/ enough attention.

Ah, ok.

>>>Then I totally agree.
>
>
> I should not have said "totally" here either. More like "almost always".
> But again, even in this case I recognize how truly heroic attempts at making
> pure code result in impossible to maintain ugly code, so my comment
> regarding the weighing of costs stands.

okeydoke.

>>>Here's something else I see *all the time*: (pseudo-java, ignore
>>>scoping rules):
>>>
>>> class A
>>> {
>>> A() { helper(); }
>>>
>>> helper() {....};
>>> }
>>>
>>> class B extends A
>>> {
>>> helper() {....}; // dangerous: overridden
>>> }
>>
>>Yup, I see that too. I see dead people.
>
>
> ...You may be seeing the people I've /killed/ for making this mistake.
> Tell'm to stop haunting me at night. Nobody needs to have ghosts chanting
> "code nazi....code nazi..." all the time...

:) I wonder what the chances are of future version of javac emitting
warnings on Bad Ideas(tm) such as we are discussing? Would love to see that.

hmmm, you can define your own meta tags in 1.5.0, can't you?

alex







 
 
Thomas G. Marshall





PostPosted: 2004-10-28 0:21:00 Top

java-programmer >> Contructor bad practices----WAS: Re: Can someone use invokeLater()... Alex Hunsley coughed up:
> Thomas G. Marshall wrote:
>> Alex Hunsley coughed up:
>>> well, if I didn't mean that, then I would be talking about calling
>>> private methods of *other classes* which wouldn't make any sense. So
>>> yes, I meant of that same object, sorry if I wasn't clear on that.
>>
>>
>> You were clear enough---I just wasn't paying /quite/ enough
>> attention.
>
> Ah, ok.
>
>>>> Then I totally agree.
>>
>>
>> I should not have said "totally" here either. More like "almost
>> always". But again, even in this case I recognize how truly heroic
>> attempts at making pure code result in impossible to maintain ugly
>> code, so my comment regarding the weighing of costs stands.
>
> okeydoke.
>
>>>> Here's something else I see *all the time*: (pseudo-java, ignore
>>>> scoping rules):
>>>>
>>>> class A
>>>> {
>>>> A() { helper(); }
>>>>
>>>> helper() {....};
>>>> }
>>>>
>>>> class B extends A
>>>> {
>>>> helper() {....}; // dangerous: overridden
>>>> }
>>>
>>> Yup, I see that too. I see dead people.
>>
>>
>> ...You may be seeing the people I've /killed/ for making this
>> mistake. Tell'm to stop haunting me at night. Nobody needs to have
>> ghosts chanting "code nazi....code nazi..." all the time...
>
> :) I wonder what the chances are of future version of javac emitting
> warnings on Bad Ideas(tm) such as we are discussing? Would love to
> see that.

Me too, but these are just "obviously stupid things", so I'm sure somebody
must have thought of them and dismissed them for some ungodly reason. For
example, there is no reason whatsoever that I can see that a compiler should
not warn on the overriding of a method called by a superclass constructor.




>
> hmmm, you can define your own meta tags in 1.5.0, can't you?
>
> alex



--
"His name was Robert Paulson. His name was Robert Paulson. His name was
Robert Paulson..."


 
 
Stefan Schulz





PostPosted: 2004-10-28 3:49:00 Top

java-programmer >> Contructor bad practices----WAS: Re: Can someone use invokeLater()... On Wed, 27 Oct 2004 16:21:23 GMT, Thomas G. Marshall
<email***@***.com> wrote:


>> :) I wonder what the chances are of future version of javac emitting
>> warnings on Bad Ideas(tm) such as we are discussing? Would love to
>> see that.
>
> Me too, but these are just "obviously stupid things", so I'm sure
> somebody must have thought of them and dismissed them for someungodly
> reason. For example, there is no reason whatsoever thatI can see that a
> compiler should not warn on the overriding of a
> method called by a superclass constructor.

This would "leak" information about implementation details of the
superclass to the child. Also, there might be legitimate reasons to
do just that. I would argue against such a practice, though. It invites
too many hard-to-find errors (initialization issues usually are)


--

Whom the gods wish to destroy they first call promising.
 
 
Thomas G. Marshall





PostPosted: 2004-10-28 11:31:00 Top

java-programmer >> Contructor bad practices----WAS: Re: Can someone use invokeLater()... Stefan Schulz coughed up:
> On Wed, 27 Oct 2004 16:21:23 GMT, Thomas G. Marshall
> <email***@***.com> wrote:
>
>
>>> :) I wonder what the chances are of future version of javac emitting
>>> warnings on Bad Ideas(tm) such as we are discussing? Would love to
>>> see that.
>>
>> Me too, but these are just "obviously stupid things", so I'm sure
>> somebody must have thought of them and dismissed them for someungodly
>> reason. For example, there is no reason whatsoever thatI can see
>> that a compiler should not warn on the overriding of a
>> method called by a superclass constructor.
>
> This would "leak" information about implementation details of the
> superclass to the child. Also, there might be legitimate reasons to
> do just that. I would argue against such a practice, though. It
> invites too many hard-to-find errors (initialization issues usually
> are)

No contention here, but I guess I don't understand the point of your reply.
We've already agreed that the practice is a bad idea and explained why (in
fact I joked that I killed folks over it)---so what are /you/ saying now? I
cannot tell from this paragraph if you are for or against (My statements
show that I am /for/) having the compiler warn on the overriding of a
helper method called by a superclass constructor.



--
"I don't want FOP, God dammit! I'm a DAPPER DAN MAN!"


 
 
Stefan Schulz





PostPosted: 2004-10-28 16:03:00 Top

java-programmer >> Contructor bad practices----WAS: Re: Can someone use invokeLater()... On Thu, 28 Oct 2004 03:31:10 GMT, Thomas G. Marshall
<email***@***.com> wrote:


>> This would "leak" information about implementation details of the
>> superclass to the child. Also, there might be legitimate reasons to
>> do just that. I would argue against such a practice, though. It
>> invites too many hard-to-find errors (initialization issues usually
>> are)
>
> No contention here, but I guess I don't understand the point of your
> reply. We've already agreed that the practice is a bad idea andexplained
> why (in fact I joked that I killed folks over it)---so whatare /you/
> saying now? I cannot tell from this paragraph if you arefor or against
> (My statements show that I am /for/) having thecompiler warn on the
> overriding of a helper method called by asuperclass constructor.

I would be _for_ having a warning when call non-final, non-static
non-private methods of the constructor's class (Since static
methods can not be overridden as well)

I would be strongly against having a warning pop up when you implement
a subclass of such a class. I think such a warning is a bad idea.
It violates encapsulation. All of a sudden you do have to care about
implementation details of a class you never knew, never wrote, and
possibly do not even understand in all details.

In both cases it should be a compiler warning instead of an error, since
(while i find it hard to imagine such a case) i can not totally rule
out a case where such a design might be the best possible solution in
terms of readability and maintainability. In such case, the special
care that needs to be excercised must be clearly documented, though.

I hope this clears things up

See you
Stefan

--

Whom the gods wish to destroy they first call promising.
 
 
Thomas G. Marshall





PostPosted: 2004-10-29 0:48:00 Top

java-programmer >> Contructor bad practices----WAS: Re: Can someone use invokeLater()... Stefan Schulz coughed up:
> On Thu, 28 Oct 2004 03:31:10 GMT, Thomas G. Marshall
> <email***@***.com> wrote:
>
>
>>> This would "leak" information about implementation details of the
>>> superclass to the child. Also, there might be legitimate reasons to
>>> do just that. I would argue against such a practice, though. It
>>> invites too many hard-to-find errors (initialization issues usually
>>> are)
>>
>> No contention here, but I guess I don't understand the point of your
>> reply. We've already agreed that the practice is a bad idea
>> andexplained why (in fact I joked that I killed folks over it)---so
>> whatare /you/ saying now? I cannot tell from this paragraph if you
>> arefor or against (My statements show that I am /for/) having
>> thecompiler warn on the overriding of a helper method called by
>> asuperclass constructor.
>
> I would be _for_ having a warning when call non-final, non-static
> non-private methods of the constructor's class (Since static
> methods can not be overridden as well)
>
> I would be strongly against having a warning pop up when you implement
> a subclass of such a class.

But *no one* is advocating that. I am suggesting that when:

*a method* of a subclass overrides a method
of a super class that is called by the superclass's
constructor

that a warning should occur. Not on any extension of such a class, no.

--
http://www.allexperts.com is a nifty way to get an answer to just about
/anything/.


 
 
Stefan Schulz





PostPosted: 2004-10-29 1:15:00 Top

java-programmer >> Contructor bad practices----WAS: Re: Can someone use invokeLater()... On Thu, 28 Oct 2004 16:47:37 GMT, Thomas G. Marshall
<email***@***.com> wrote:

>> I would be strongly against having a warning pop up when you implement
>> a subclass of such a class.
>
> But *no one* is advocating that. I am suggesting that when:
>
> *a method* of a subclass overrides a method
> of a super class that is called by the superclass's
> constructor
>
> that a warning should occur. Not on any extension of such a class, no.

That is exactly what would happen. If i would implement a Subclass, and
override method A, suddenly my compiler would tell me "Don't do that,
whoever wrote the Superclass calls that method in the constructor". So
encapsulation is down the drain.

If you want a warning, put it when you implement the constructor
that relies on such "unreliable" methods.


--

Whom the gods wish to destroy they first call promising.
 
 
Thomas G. Marshall





PostPosted: 2004-10-29 3:05:00 Top

java-programmer >> Contructor bad practices----WAS: Re: Can someone use invokeLater()... Stefan Schulz coughed up:
> On Thu, 28 Oct 2004 16:47:37 GMT, Thomas G. Marshall
> <email***@***.com> wrote:
>
>>> I would be strongly against having a warning pop up when you
>>> implement a subclass of such a class.
>>
>> But *no one* is advocating that. I am suggesting that when:
>>
>> *a method* of a subclass overrides a method
>> of a super class that is called by the superclass's
>> constructor
>>
>> that a warning should occur. Not on any extension of such a class,
>> no.
>
> That is exactly what would happen. If i would implement a Subclass,
> and override method A, [...]

No, that's different! You *originally* said:

I would be strongly against having a warning pop
up when you implement a subclass of such a class.

Which is not the issue, and would not happen in my scenario. It is when a
method in the sub class /overrides/ such a method in the superclass. Not
just when something extends that (super)class.



--
Everythinginlifeisrealative.Apingpongballseemssmalluntilsomeoneramsitupyourn
ose.


 
 
Stefan Schulz





PostPosted: 2004-10-29 4:54:00 Top

java-programmer >> Contructor bad practices----WAS: Re: Can someone use invokeLater()... On Thu, 28 Oct 2004 19:05:28 GMT, Thomas G. Marshall
<email***@***.com> wrote:

>
> Which is not the issue, and would not happen in my scenario. It is when
> a method in the sub class /overrides/ such a method in the superclass.
> Not
> just when something extends that (super)class.

My point is, it _can_ happen anytime you extend the superclass and
overwrite
_any_ method. It breaks encapsulation, and therefore is not a good idea.

--

Whom the gods wish to destroy they first call promising.
 
 
xarax





PostPosted: 2004-10-29 6:09:00 Top

java-programmer >> Contructor bad practices----WAS: Re: Can someone use invokeLater()... "Stefan Schulz" <email***@***.com> wrote in message
news:opsglbjxp0q1fd9p@localhost...
> On Thu, 28 Oct 2004 16:47:37 GMT, Thomas G. Marshall
> <email***@***.com> wrote:
>
> >> I would be strongly against having a warning pop up when you implement
> >> a subclass of such a class.
> >
> > But *no one* is advocating that. I am suggesting that when:
> >
> > *a method* of a subclass overrides a method
> > of a super class that is called by the superclass's
> > constructor
> >
> > that a warning should occur. Not on any extension of such a class, no.
>
> That is exactly what would happen. If i would implement a Subclass, and
> override method A, suddenly my compiler would tell me "Don't do that,
> whoever wrote the Superclass calls that method in the constructor". So
> encapsulation is down the drain.
>
> If you want a warning, put it when you implement the constructor
> that relies on such "unreliable" methods.

And if you want to make such a method "reliable",
just add "final" to the method signature.

Otherwise, we should trust the programmer to know
that non-final, non-private instance methods can be
overridden in subclasses and the programmer is ok with
that.

OTOH, a "lint" type utility may exist that can provide
such a warning for superclass. That is probably where
the warning belongs (in a lint utility rather than the
compiler).

2 cents worth.


 
 
Thomas G. Marshall





PostPosted: 2004-10-29 9:22:00 Top

java-programmer >> Contructor bad practices----WAS: Re: Can someone use invokeLater()... Stefan Schulz coughed up:
> On Thu, 28 Oct 2004 19:05:28 GMT, Thomas G. Marshall
> <email***@***.com> wrote:
>
>>
>> Which is not the issue, and would not happen in my scenario. It is
>> when a method in the sub class /overrides/ such a method in the
>> superclass. Not
>> just when something extends that (super)class.
>
> My point is, it _can_ happen anytime you extend the superclass and
> overwrite
> _any_ method. It breaks encapsulation, and therefore is not a good
> idea.

Which isn't what you said, but fine----let's run with that. Yes of course
it's bad, we've all been over this, now given that, /why/ don't you want a
warning for it?

--
Onedoctortoanother:"Ifthisismyrectalthermometer,wherethehell'smypen???"



 
 
Chris Uppal





PostPosted: 2004-10-29 17:07:00 Top

java-programmer >> Contructor bad practices----WAS: Re: Can someone use invokeLater()... Thomas G. Marshall wrote:

> Which isn't what you said, but fine----let's run with that. Yes of course
> it's bad, we've all been over this, now given that, /why/ don't you want a
> warning for it?

because the error is in the way the constructor is coded, not in the fact that
a perfectly innocent subclass is overriding a perfectly innocent method. As
Stefan said, if you want a warning then it should be issued when the compiler
sees a call to a non-private, non-final, method from the constructor.

Incidentally, another reason why you have to do it that way around is that
neither you nor the compiler know what the definitions of any other methods
(including constructors) will be at runtime. So when compiling a constructor
it /cannot/ know what methods will be overridden (unless they are
private/final); and when compiling a method it /cannot/ know what the
definitions of the constructors of superclasses will be.

-- chris



 
 
Thomas G. Marshall





PostPosted: 2004-10-29 21:57:00 Top

java-programmer >> Contructor bad practices----WAS: Re: Can someone use invokeLater()... Chris Uppal coughed up:
> Thomas G. Marshall wrote:
>
>> Which isn't what you said, but fine----let's run with that. Yes of
>> course it's bad, we've all been over this, now given that, /why/
>> don't you want a warning for it?
>
> because the error is in the way the constructor is coded, not in the
> fact that a perfectly innocent subclass is overriding a perfectly
> innocent method. As Stefan said, if you want a warning then it
> should be issued when the compiler sees a call to a non-private,
> non-final, method from the constructor.
>
> Incidentally, another reason why you have to do it that way around is
> that neither you nor the compiler know what the definitions of any
> other methods (including constructors) will be at runtime. So when
> compiling a constructor it /cannot/ know what methods will be
> overridden (unless they are private/final); and when compiling a
> method it /cannot/ know what the definitions of the constructors of
> superclasses will be.

Ok, point *very* well made. But there is still something not quite right,
lemme state it better:

Given class A, helper() and B, helper() (in standard examples)

javac cannot tell with certainty whether or not the A() is calling helper()
but it /can/ determine so to a first approximation. To avoid having to
actually sniff the byte code, javac could maintain a list of the overridable
methods /actually called/ by A(), which by the way, may happen (enough so)
already---I'm not sure what the symbol table looks like in .class files.

The problem /only exists/ when the method is actually overriden in B, not
when A() calls it.

Now that you cleared the fog from my eyes, the idea of issuing a warning
when A() calls an overrid/able/ method is not bad, but still has the same
problem. There is no way to tell if A.helper()is truly called
programmatically from A() or not. Thus in *both* cases the warning would
be:

Warning: B overrides a method possibly called by constructor in A

Warnings need not ferret out all possibilities. Nor do errors. In fact, a
class cast exception is caught by the compiler when it can, and at runtime
when it cannot.


--
"It's easier to be terrified by an enemy you admire."
-Thufir Hawat, Mentat and Master of Assassins to House Atreides


 
 
Thomas G. Marshall





PostPosted: 2004-10-29 21:59:00 Top

java-programmer >> Contructor bad practices----WAS: Re: Can someone use invokeLater()... Thomas G. Marshall coughed up:
> Chris Uppal coughed up:
>> Thomas G. Marshall wrote:
>>
>>> Which isn't what you said, but fine----let's run with that. Yes of
>>> course it's bad, we've all been over this, now given that, /why/
>>> don't you want a warning for it?
>>
>> because the error is in the way the constructor is coded, not in the
>> fact that a perfectly innocent subclass is overriding a perfectly
>> innocent method. As Stefan said, if you want a warning then it
>> should be issued when the compiler sees a call to a non-private,
>> non-final, method from the constructor.
>>
>> Incidentally, another reason why you have to do it that way around is
>> that neither you nor the compiler know what the definitions of any
>> other methods (including constructors) will be at runtime. So when
>> compiling a constructor it /cannot/ know what methods will be
>> overridden (unless they are private/final); and when compiling a
>> method it /cannot/ know what the definitions of the constructors of
>> superclasses will be.
>
> Ok, point *very* well made. But there is still something not quite
> right, lemme state it better:
>
> Given class A, helper() and B, helper() (in standard examples)
>
> javac cannot tell with certainty whether or not the A() is calling
> helper() but it /can/ determine so to a first approximation. To
> avoid having to actually sniff the byte code, javac could maintain a
> list of the overridable methods /actually called/ by A(), which by
> the way, may happen (enough so) already---I'm not sure what the
> symbol table looks like in .class files.
>
> The problem /only exists/ when the method is actually overriden in B,
> not when A() calls it.

Strike. I meant that the problem only exists when B.helper() overrides
A.helper(), not when A() calls A.helper() normally.


>
> Now that you cleared the fog from my eyes, the idea of issuing a
> warning when A() calls an overrid/able/ method is not bad, but still
> has the same problem. There is no way to tell if A.helper()is truly
> called programmatically from A() or not. Thus in *both* cases the
> warning would be:
>
> Warning: B overrides a method possibly called by constructor in A
>
> Warnings need not ferret out all possibilities. Nor do errors. In
> fact, a class cast exception is caught by the compiler when it can,
> and at runtime when it cannot.



--
"It's easier to be terrified by an enemy you admire."
-Thufir Hawat, Mentat and Master of Assassins to House Atreides