this.wait( sleep );

C

Chris Smith

Jon said:
That document shows that certain methods in the Thread class should
never have been there in the first place. I don't think it shows that
the remaining methods are badly designed.

Jon,

In context, the link was intended (in that other subthread) to show that
Sun provides sample code that calls sleep as if it were an instance
method. Indeed, they do exactly that, and they are even worse because
they call sleep on declared reference variables, and you have to look
elsewhere to see that this variable was initialized to the current
thread.

Nothing new there, though, in terms of whether it's a good idea...
unless you want to imply that anything that happens in code written by
Sun is good practice (and that's a scary thought, indeed, for any of us
who've read much Sun code!)

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
J

Jon Skeet

Chris Smith said:
In context, the link was intended (in that other subthread) to show that
Sun provides sample code that calls sleep as if it were an instance
method.

Ah, right.
Indeed, they do exactly that, and they are even worse because
they call sleep on declared reference variables, and you have to look
elsewhere to see that this variable was initialized to the current
thread.
Bletch.

Nothing new there, though, in terms of whether it's a good idea...
unless you want to imply that anything that happens in code written by
Sun is good practice (and that's a scary thought, indeed, for any of us
who've read much Sun code!)

:)
 
R

Ricardo

Jon said:
Not if you make sure they're always called using appropriate syntax, ie

Thread.sleep(...)
someThread.start()

That leads to the *obvious* question on the part of the reader, "Which
thread is being put to sleep?" Now, in my view the obvious answer is
"the current one", but if the answer isn't obvious, the reader can look
at the API. No "false knowledge" is being implied with the above code -
it *is* being implied using your syntax.

From a readability point of view, the obvious would've been instantly
communicated the other way. False knowledge, if implied, is due to
having concurrency controls in the same class as Thread, and even worse,
named in such a deceiving manner that false knowledge is easily acquired.
 
R

Ricardo

Jon said:
The change now could be just for 1.5 and onwards (say) - if you specify
-source 1.5 it could turn it into an error then, leaving old code
working the same way if you don't specify the -source option.




We certainly do. I find it odd that you believe it would be a good
change to make what you consider a good practice to be an error. I
prefer to treat it as an error already (in Eclipse) because I consider
it a *bad* practice.

The change will protect innocent victims of the Thread class, and that's
a trade-off that I can live with. However, when the language doesn't
call for such a rule, it's the responsibility of the class designer to
properly define classes, and most importantly, provide method names that
are meaningful enough for the sake of readability and proper use, and
safe enough that when called from an instance (as currently is legal),
they'd behave as expected. Some static helper class could serve as a
good place for calls to sleep and yield the current thread, not the
Thread class.
 
R

Ricardo

Jon said:
Ricardo wrote:

I don't dispute that it's bee around for a long time.

However I tend to see that it's just as easily due to the "rouge tile"
or similar bug pattern.

(for those who aren't familiar with it, basically copy-n-paste propoates
a bug or bad code from one place to another)

You're making an assumption that you can't back up. Those calls are
made in the fashion that they are, for a purpose. They're neither buggy
nor error-prone. Copy & Paste is without a doubt a nasty and a very
common habit. However, I doubt that the call we're discussing is a
result of such an act; and even if it were, it's *safe* and *error free*.
And just for the record, when at the company where I learned Java, one
senior programmer spent a week walking the halls cussing Gosling up one
side and down the other for some of his actual coding. Steve McConnell's
books also back up that being a good designer and constructing good code
do not always go hand-in-hand.

Perhaps the Thread class is a good example.
 
C

Chris Smith

Ricardo said:
From a readability point of view, the obvious would've been instantly
communicated the other way. False knowledge, if implied, is due to
having concurrency controls in the same class as Thread, and even worse,
named in such a deceiving manner that false knowledge is easily acquired.

Do you intend to go on claiming that the implications of code written to
call static methods as if they are instance methods is the fault of the
language? If so, fine. Whatever you think. The fact remains that, in
the language we've got, those implications exist.

I just don't see why it's such a big deal that someone seeing
Thread.sleep for the first time would have to look up what it does.
Once you've looked it up once, you already know and then it all makes
sense from there on out.

--
www.designacourse.com
The Easiest Way to Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
J

Jon A. Cruz

Ricardo said:
You're making an assumption that you can't back up. Those calls are
made in the fashion that they are, for a purpose. They're neither buggy
nor error-prone.

No. I was saying that the presence of a particular idiom is often just
simply the result of copying existing code and 'keeping consistent'
rather than carefully thought out code construction.

Copy & Paste is without a doubt a nasty and a very
common habit. However, I doubt that the call we're discussing is a
result of such an act; and even if it were, it's *safe* and *error free*.

Well, "safe" and "error free" are mainly opinions.

They perhaps are such if one considers only the immediate use of the
code. However, if one considers long term maintainability and misleading
newer programmers, then they are not.
 
R

Ricardo

Chris said:
Do you intend to go on claiming that the implications of code written to
call static methods as if they are instance methods is the fault of the
language? If so, fine. Whatever you think. The fact remains that, in
the language we've got, those implications exist.

What I'm saying is that providing a class with an interface where a
class method is called from an instance (which is legal), should be safe
enough that *a user* would not be trapped and swallowed by a black hole.
I just don't see why it's such a big deal that someone seeing
Thread.sleep for the first time would have to look up what it does.
Once you've looked it up once, you already know and then it all makes
sense from there on out.

For readability's sake, the other syntax is straight to the point. But
it's been blamed for causing users to make t.sleep(..) calls, and that's
what I have a problem with. Blaming a syntax that seeks readability for
the trap of a malicious class is what *bogus* is. Calling static
methods from an instance should be avoided, but class/static methods
*must* be safe/clear/precise/concise/... especially when they put a
thread to sleep, and not just any thread.
 
R

Ricardo

Jon said:
No. I was saying that the presence of a particular idiom is often just
simply the result of copying existing code and 'keeping consistent'
rather than carefully thought out code construction.

Cool! And that's definitely a source of many, many bugs.
Well, "safe" and "error free" are mainly opinions.

They perhaps are such if one considers only the immediate use of the
code. However, if one considers long term maintainability and misleading
newer programmers, then they are not.

Again here Jon, it's a question of what's misleading the new programmer.
Is it the syntax or the interface of class Thread?
 
J

Jon Skeet

Ricardo said:
From a readability point of view, the obvious would've been instantly
communicated the other way. False knowledge, if implied, is due to
having concurrency controls in the same class as Thread, and even worse,
named in such a deceiving manner that false knowledge is easily acquired.

It's only "easily acquired" if code such as the type you encourage is
used.
 
J

Jon Skeet

Ricardo said:
The change will protect innocent victims of the Thread class, and that's
a trade-off that I can live with. However, when the language doesn't
call for such a rule, it's the responsibility of the class designer to
properly define classes, and most importantly, provide method names that
are meaningful enough for the sake of readability and proper use, and
safe enough that when called from an instance (as currently is legal),
they'd behave as expected. Some static helper class could serve as a
good place for calls to sleep and yield the current thread, not the
Thread class.

And when the language has failed and the library doesn't meet your
personal taste (I have no problem with it), the correct response is
*not* to write misleading code. A far better solution to your perceived
problem would be for you to write your own class called CurrentThread
which had the appropriate static methods which merely forwards the
methods.
 
J

Jon Skeet

Ricardo said:
Again here Jon, it's a question of what's misleading the new programmer.
Is it the syntax or the interface of class Thread?

The syntax of the language leaves it open to abuse. The design of the
class makes that abuse more likely. Your own abuse of it encourages
further abuse.
 
D

Dale King

P.Hill said:
Oh don't show him that, for it only says "Avoid" not
"Don't ever", now he's got wiggle room! :)

I've actually been tempted sometimes to deliberately use the pattern to
shorten some static method calls to make them fit better on a line. Luckily,
I've resisted the temptation and when we get static import in JDK1.5 it will
become unnecessary.

For example, if you start dealing with code like:

AffineTransform rotation = AffineTransform.getRotateInstance(
Math.toRadians( 45 ), 16, 16 );

There is no way to get that to fit in 80 characters. You start wishing that
you can do things like:

AffineTransform at = null; // Just to reduce line of length
AffineTransform rotation = at.getRotateInstance( Math.toRadians( 45 ),
16, 16 );

But thankfully, static import will eliminate this.
 
D

Dale King

Ricardo said:
What I'm saying is that providing a class with an interface where a
class method is called from an instance (which is legal), should be safe
enough that *a user* would not be trapped and swallowed by a black hole.

Probably making a big mistake joining this thread, but there are several
misconceptions there. The interface of the class does is not the one that
allows you to call the class method with a syntax that looks like it is
calling an instance method. It is the language. There is nothing the
interface can do about it.

You certainly can make a credible argument that perhaps it should have been
called Thread.sleepCurrentThread() to make it more explicit. To which all we
can say is hindsight is 20/20. It is too much of a leap to then say that we
should use misleading syntax to compensate.

And there is an error in your statement. The class method is not called from
an instance at all. The static method is called according to the type of the
variable not by the type of the instance. The variable could even be null.

Here is another way that the syntax could lead to confusion. Consider if we
for some reason wanted to do logging of operations on Threads. So we might
create:

public class LoggedThread extends Thread
{
public static void sleep( long millis ) throws InterruptedException
{
log( "Thread going to sleep" );
Thread.sleep( millis );
log( "Thread woken up" );
}
...

Some unsuspecting user used might do:

Thread myThread = new LoggedThread( someRunnable );
...
myThread.sleep( 500 );

They will probably have trouble figuring out why the logging messages do not
show up.
 
D

Dale King

Jon Skeet said:
Not to the normal Java compiler, no. Eclipse uses its own compiler,
which is how it is able to add warnings like this.

There is no reason that the normal Java compiler could not generate warnings
for this as well or at least add an option to turn on such warnings. I see
no problem with deprecation being applied to code constructs as well. They
added an -Xswitchcheck option in JDK1.5 that will generate warnings for use
of fallthrough in switch statements.
 
D

Dale King

Ricardo said:
Jon Skeet wrote:
The change will protect innocent victims of the Thread class, and that's
a trade-off that I can live with. However, when the language doesn't
call for such a rule, it's the responsibility of the class designer to
properly define classes, and most importantly, provide method names that
are meaningful enough for the sake of readability and proper use, and
safe enough that when called from an instance (as currently is legal),
they'd behave as expected.

Let's divide that because you have to separate thoughts here. First thought
is:

"it's the responsibility of the class designer to provide method names that
are meaningful enough for the sake of readability and proper use."

I cannot argue against that. It might have been better to call it
sleepCurrentThread instead of sleep for the static method. Unfortunately,
it's too late now. We're stuck with sleep.

The second thought is:
"it's the responsibility of the class designer to properly define classes
[that are] safe enough that when called from an instance (as currently is
legal) [and] behave as expected."

I am a bit baffled by this one. How exactly do you propose that be
accomplished? If it's the responsibility of the class designer to define the
class so it is safe and behaves as expected when "called from an instance"
(which technically is not what happens), please enlighten us how a designer
actually does that. I certainly see no way to do it.

A static method has no way of knowing if you used an instance variable to
choose the class to invoke it. It's just a static method. The only way to be
safe and behave as expected is if it knew the value of the variable, but it
doesn't have access to that information.
 
L

Lee Fesperman

Dale said:
Ricardo said:
Jon Skeet wrote:
The change will protect innocent victims of the Thread class, and that's
a trade-off that I can live with. However, when the language doesn't
call for such a rule, it's the responsibility of the class designer to
properly define classes, and most importantly, provide method names that
are meaningful enough for the sake of readability and proper use, and
safe enough that when called from an instance (as currently is legal),
they'd behave as expected.

The second thought is:
"it's the responsibility of the class designer to properly define classes
[that are] safe enough that when called from an instance (as currently is
legal) [and] behave as expected."

I am a bit baffled by this one. How exactly do you propose that be
accomplished? If it's the responsibility of the class designer to define the
class so it is safe and behaves as expected when "called from an instance"
(which technically is not what happens), please enlighten us how a designer
actually does that. I certainly see no way to do it.

All of your points are excellent and correct, except you could do it. The one safe way
to do this is to create classes that have only static or only instance methods. However,
the cure is worse than the disease.

BTW, you would need to add a private ctor to your static-only class to prevent cheating
;^)
 
J

Jon Skeet

Lee Fesperman said:
BTW, you would need to add a private ctor to your static-only
class to prevent cheating
;^)

That wouldn't stop the methods being called on what *looks* like an
instance:

Math x = null;
double foo = x.cos (something);

will work fine.
 
L

Lee Fesperman

Jon said:
That wouldn't stop the methods being called on what *looks* like an
instance:

Math x = null;
double foo = x.cos (something);

will work fine.

Right. I guess we'll just have to ban static methods altogether ;^)

Following in the same vein, classes would always specify whether they were static-only
and instance-only, so everyone would know the meaning of the above. For example:
MathStatic ... YAS (Yet Another Smiley)

BTW, the 'cheating' I was referring to was creating an instance of a static-only class
and in order to call the public instance methods inherited from java.lang.Object.
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top