Can someone use invokeLater() to call a public method from a JPanel?

X

xarax

Alex Hunsley said:
Thomas said:
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.
 
T

Thomas G. Marshall

xarax coughed up:
Alex Hunsley said:
Thomas said:
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.
 
T

Thomas G. Marshall

Alex Hunsley coughed up:
Thomas said:
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.


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.

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

Alex Hunsley

Thomas said:
Alex Hunsley coughed up:

...[rip]...


One last question: in which way is it smart to alienate the people who
are trying to help you?


You were helpful.

However, to the side of your reply, I am sensing a growing sense of rudeness
in the replies in programming ng's. It sometimes takes the following form:

OP: humble question, please, I'm humble
RP: this is a horrible idea, and do your research better
OP: that is rude!

I think it may have something to do with the relatively recent rush of
students to the ng's asking for their homework to be completed for them, and
that /that/ is tiring for the frequent contributors to deal with over and
over. But there seems to be something more here, and I haven't yet put my
finger on it.

Again, this is to the side of your post. It's just an observation in
general that I've made.

Thomas,
yup, I think I've seen a bit of what you mean. The rush of newbies and
their cluelessness can be frustrating, yes, which may explain the
increasingly impatient attitude in some quarters....
 
A

Alex Hunsley

xarax said:
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.
 
A

Alex Hunsley

Thomas said:
Alex Hunsley coughed up:


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

Ah, ok.
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.



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

Thomas G. Marshall

Alex Hunsley coughed up:
Ah, ok.


:) 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.
 
S

Stefan Schulz

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)
 
T

Thomas G. Marshall

Stefan Schulz coughed up:
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.
 
S

Stefan Schulz

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
 
T

Thomas G. Marshall

Stefan Schulz coughed up:
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.
 
S

Stefan Schulz

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

Thomas G. Marshall

Stefan Schulz coughed up:
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.
 
S

Stefan Schulz

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

xarax

Stefan Schulz said:
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.
 
T

Thomas G. Marshall

Stefan Schulz coughed up:
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?
 
C

Chris Uppal

Thomas said:
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
 
T

Thomas G. Marshall

Chris Uppal coughed up:
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.
 
T

Thomas G. Marshall

Thomas G. Marshall coughed up:
Chris Uppal coughed up:

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

Thomas G. Marshall

Thomas G. Marshall coughed up:
Thomas G. Marshall coughed up:

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

Strike two. I meant (OI) that the problem only exists when A() calls
B.helper() through poly-m, not when A() calls A.helper() normally.

Go ahead, give me a "strike three". :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,444
Messages
2,571,709
Members
48,796
Latest member
Greg L.
Top