Joshua Bloch -- Strangeness of Java

V

Veloso

Joshua Bloch gives an interesting interview (http://java.sun.com/
developer/technicalArticles/Interviews/bloch_effective_08_qa.html) on
java.sun.com, promoting the revised version of “Effective Java”
wherein he talks about generics, enums, annotations, the under-use of
Java libraries, the importance of minimizing the accessibility of
classes and members and minimizing mutability, and other matters.

But the one question I’d never heard asked was, “What’s the strangest
thing about the Java platform?” His answer: “I'm going to say that the
strangest thing about the Java platform is that the byte type is
signed. I've never heard an explanation for this. It's quite
counterintuitive and causes all sorts of errors.”

Two questions. Does anyone have an explanation as to why the byte type
is signed? And what is your candidate for the strangest thing about
the Java platform?
 
J

Joshua Cranmer

Veloso said:
Two questions. Does anyone have an explanation as to why the byte type
is signed? And what is your candidate for the strangest thing about
the Java platform?

I have a few guesses:
1. Unsigned types were pulled late in the process and no one thought to
change byte to unsigned.
2. The other integral types (short, int, and long) are all signed. Byte
was originally signed for consistency without the developers thinking
about the impact on the most common use cases.

As for the strangest thing, I have to +1 the signed byte thing. It's
always the first thing on the tip of my tongue when I mention features I
wish to see in a perfect Java.
 
M

Mike Schilling

Veloso said:
Two questions. Does anyone have an explanation as to why the byte
type
is signed? And what is your candidate for the strangest thing about
the Java platform?

Inner classes. Their most common uses are handled much more
intuitively by method pointers.
 
H

Harold Yarmouth

Mike said:
Inner classes. Their most common uses are handled much more
intuitively by method pointers.

Including iterators? These "method pointers" would have to be able to
carry a context with them that was distinct for each invocation of the
method-pointer-returning method. I.e. would have to be closures.

Anonymous inner classes perhaps.

Allowing function literals and use of static methods as
first-class-object functions would let you get rid of many of the
commonest anonymous inner classes -- Runnable, ActionListener, etc. --
but the multi-method event listeners would need to be handled
differently. Preferably by deprecating the lot of them and adding a new
event framework that puts all of the important information in the event
objects, has more separated events, and so forth. And gets rid of event
component getting. That leads to lots of ugly code, switches,
instanceofs, and casts included.

My usual pattern of use of event listeners is to use two different ones
where I want two different behaviors. So if button A should do X and
button B should do Y, I don't have

public void actionPerformed (ActionEvent e) {
Component c = // etc.
if (c == buttonA) doX();
if (c == buttonB) doY();
// etc.
}

but rather a button A action listener and a separate button B action
listener.

So which component can be inferred by which listener we're in.

For ActionEvent, this means I tend never to even refer to the event
object. A simple "somethingGotClicked()" callback with no args would
have done as well, methinks.

For other listeners ...

Well, consider WindowListener.

void windowOpened(WindowEvent e);
void windowClosing(WindowEvent e);
void windowClosed(WindowEvent e);
void windowIconified(WindowEvent e);
void windowDeiconified(WindowEvent e);
void windowActivated(WindowEvent e);
void windowDeactivated(WindowEvent e);

and WindowFocusListener

void windowGainedFocus(WindowEvent e);
void windowLostFocus(WindowEvent e);

and WindowStateListener

void windowStateChanged(WindowEvent e);

The latter supersedes windowIconified and windowDeiconified from
WindowListener, and puts all information needed in the event.

WindowFocusListener's methods likewise supersede windowActivated and
windowDeactivated. They could be combined into a single method,
windowFocusChanged(boolean nowFocused), with the focus state change in a
parameter, or encoded in an event object if that model was kept.

That leaves WindowListener with windowOpened, windowClosing, and
windowClosed.

The semantics of these are tricky and sometimes wacky.

A windowOpened that is only called once when a window is first
constructed might as well just be inlined in the code that builds the
window. This could stand to go away. Right now its only use is if a
window is constructed but not immediately shown, and something is lazily
initialized only when it's shown. The showing code can as easily lazily
create the whole damn window when it's first shown, e.g. by invoking a
singleton-returning factory method (if there's only going to be the one
window in the app), or (if it isn't supposed to preserve state across
user-visible instances) create a new one each time and dispose it when done.

Getting rid of that leaves windowClosing and windowClosed. Closing has
tricky semantics -- is it hiding-or-disposing or only disposing? Does it
count if the close box is clicked but the window has DO_NOTHING_ON_CLOSE
set?

I'd redesign this so that there was a WindowCloseButtonListener and the
options were DO_NOTHING_ON_CLOSE (greys the "X" button), HIDE_ON_CLOSE,
DISPOSE_ON_CLOSE, and a new one, GENERATE_EVENT_ON_CLOSE. Setting this
last would make the "X" button enabled and cause it to call a
WindowCloseBoxListener when clicked. This could hide or dispose the
window, return without doing either, pop up a "you have unsaved changes?
are you sure?", or whatever, at the coder's pleasure, more or less as
windowClosing is currently used. The other choices would behave exactly
like (and be implemented under the hood as) a listener that just does a
setVisible(false) or a dispose(), aside from DO_NOTHING, which disables
the button.

(And there really should be obvious ways to enable/disable the maximize
and, separately, the minimize buttons, too. Affecting their
corresponding window-icon-menu items. With appropriate translations to
other platforms.)

And we're left with windowClosed, which might be made the sole method of
a WindowCloseListener. This would run if a window was hidden or
disposed, and get a boolean parameter or an event object containing a
boolean that was "true" if the window was disposed.

That's the window listeners (and the old ones would be preserved, with
their present semantics, for compatibility purposes, but deprecated).
 
R

Roedy Green

Two questions. Does anyone have an explanation as to why the byte type
is signed? And what is your candidate for the strangest thing about
the Java platform?

It is inherited from the original C. It made more sense back then
when chars were 7-bits. It also may trace back to the instruction set
of the PDP-11. I have not coded PDP-11 since the early 80s.
 
R

Roedy Green

But the one question I’d never heard asked was, “What’s the strangest
thing about the Java platform?”

I would say it is the generics syntax. It is a bit like a seat belt
that requires a garage technician to help lock and undo.
 
M

Mike Schilling

Roedy said:
On Tue, 28 Oct 2008 20:56:49 -0700 (PDT), Veloso
someone
who said :


It is inherited from the original C.

C left it up to the implementation whether chars were signed or
unsigned.
 
M

Mike Schilling

Roedy said:
On Tue, 28 Oct 2008 20:56:49 -0700 (PDT), Veloso
someone
who said :


I would say it is the generics syntax. It is a bit like a seat belt
that requires a garage technician to help lock and undo.

It's ugly but not strange, in that it's adopted from C++.
 
M

Mike Schilling

Eric said:
I've always supposed that the signedness of Java's byte is an
illustration of Emerson's famous observation about consistency.

The why aren't chars signed? Presumably because while a char is
techinically an integral type, it's really used to hold characters
rather than numbers, and sign-extending them would be foolish. The
answer, then, is that bytes are signed because they were considered to
be small integers, rather than (more sensibly) non-numeric octets..
 
D

Daniel Pitts

Mike said:
Inner classes. Their most common uses are handled much more
intuitively by method pointers.
Do you mean inner classes or anonymous classes?

I actually find both of those more intuitive (but/and less terse) than
method pointers.

The strangest thing about Java to me is the overloading of "final" and
the lack of a concept that is the same as c++ "const *".

The second strangest thing IMO is erasure.
 
M

Mike Schilling

Daniel said:
Do you mean inner classes or anonymous classes?

Both. I have no problem with a nested class special access to its
containing class's private parts, but if you want object A to point to
object B, you can pass B into A's constructor.
I actually find both of those more intuitive (but/and less terse)
than
method pointers.

I disagree. I wrote a rant about that once; let me see if I can find
it. Oh, here we go:

Assume we're introducing only the bound method pointer, that is, an
object
that:

o - is typed just as a method is, with a specific "this" type,
argument
types, and return type.
o - when created, is bound to a "this" object and a method name
o - does only one thing after being created -- call the method it was
bound
to

I submit that, to anyone familiar with OO (in particular, dispatch of
virtual functions), the idea of an object that encapsulates a method
call is
an obvious one. I submit further that there are no bothersome
subtleties
here. Having written one test program that used these method
pointers,
you'll know exactly how they work, and the answers to whatever
questions
might be raised are obvious.

Q: What if the object gets collected?
A. The method pointer references it, so it can't be collected wile the
pointer's still live.

Q. What thread does the called method run on?
A. The same thread as the caller, like any other method.

Q. How many times can I use a single method pointer?
A. As many times as you like, just as you could call the method
directly as
many times as you like.

Anonymous classes are, I submit a bit more complex. Yes, they're
classes,
and that answers a lot of questions about them. But their access to
the
private parts of their enclosing class (necessary, if they're going to
be
useful callback handlers) introduces more complicated and somewhat
arbitrary
behavior:

Q. But what use are they if they can only invoke public behavior on
their
enclosing class?
A. Exactly. That's why they can access private parts of their
enclosing
class too. And their enclosing classes can access their private parts
too.

Q. Why that last part?
A. Umm, symmetry. And they can access final members of the block that
creates them.

Q. You mean, scalars and strings, that are truly constant?
A. No, objects too. Including mutable ones.

Q. So the anonymous class can access an object that might change out
from
under it, but not an object *reference* that might change out from
under it?
A. Exactly.

Q. And I can define static members of the anonymous class, to define
properties that all of the instances will have in common?
A. No.

Q. Why not?
A. Because. But you *can* define them as statics on the containing
class,
further away from where they're used, and with nothing syntactic to
indicate
that they're intended as part of the anonymous class.

Q. OK, I feel better. But it seems to me that the purpose of the
anonymous class is to make its methods as much as possible like
methods of
its enclosing class, while allowing them to be run from a wider
selection of
callers, for instance, via callback interfaces the enclosing class
doesn't
implement.
A. Exactly.

Q. Then why not have a mechanism where the method *can* be part of the
enclosing class, and be called via something other than its name?
A. Because that would be complicated.
 
L

Lew

Mike said:
I disagree. I wrote a rant about that once; let me see if I can find
it. Oh, here we go:

I agree with Daniel. But it's obviously a matter of opinion.

Some people are just not going to be happy until Java sports closures. Me, I
don't care - I'm too busy writing effective, useful Java code without them.
 
A

Arne Vajhøj

Veloso said:
Joshua Bloch gives an interesting interview (http://java.sun.com/
developer/technicalArticles/Interviews/bloch_effective_08_qa.html) on
java.sun.com, promoting the revised version of “Effective Java”
wherein he talks about generics, enums, annotations, the under-use of
Java libraries, the importance of minimizing the accessibility of
classes and members and minimizing mutability, and other matters.

But the one question I’d never heard asked was, “What’s the strangest
thing about the Java platform?” His answer: “I'm going to say that the
strangest thing about the Java platform is that the byte type is
signed. I've never heard an explanation for this. It's quite
counterintuitive and causes all sorts of errors.”

Two questions. Does anyone have an explanation as to why the byte type
is signed? And what is your candidate for the strangest thing about
the Java platform?

I agree about the signed byte being a PITA. I have cursed over
that hundreds of times. It does not make any sense. C# got that
as it should have been.

Why ? My guess is that it was a 10000 feet decision - let us make
all integer types signed.

I think the weirdest thing in Java is inner classes.

Arne
 
A

Arne Vajhøj

Mike said:
It's ugly but not strange, in that it's adopted from C++.

I would say that the syntax inherited from C++ is the pretty
part.

The semantics are the real problem.

I mean it works great when used for ArrayList<X> and HashMap<Y,Z>,
but when people start nesting, binding and using interfaces then
it becomes very complex to understand.

Arne
 
L

Lew

Arne said:
Yep.

But if you look at how delegates work in C# especially
with anonymous methods and lambda, then the arguments
does not match reality.

They must have thought so, to say:
 
M

Mike Schilling

Arne said:
that hundreds of times. It does not make any sense. C# got that
as it should have been.

C# had Java's mistakes to learn from; Java didn't.
 
L

Lew

Mike said:
That was written while Java was suing Microsoft for introducing method
pointers into Java. I suspect that might have affected its
conclusions.

Suspect away, but it's not mentioned at all. All the logic and evidence they
provide is based on other factors.

Also, the copyright date on the article is 1994-2008, suggesting that at least
some of the discussion must predate the 1997 lawsuit.
 

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,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top