I have written a post about hidden feature of java on my blog.
If you're interested in things like nondeterministic behaviors
(fun with finalizers anyone?) and all the
"but-it's-in-the-spec-look-at-section-x-y-z" gotchas,
you'll enjoy books like "Effective Java" and "Java puzzlers".
The very fact that there's a 300 page books (and online add-ons)
dedicated to Java puzzling weirdities speaks volume.
Anyway to me the most "hidden" feature of Java is that it
actually is an OO language, yet it actually encourages and
facilitates both procedural-style and goto-style programming.
A guestimate would be that 99% of all Java programs out there
are actually just C programs in a Java shell.
The presence of equals() in the Object class is, to me, the
most broken thing in Java.
It is fundamentally incompatible with real OO modeling,
unless you decide not to use equals() at all.
Most programmers don't realize it, because they don't realize
they're actually doing procedural programming (and they're
perfectly happy with the non-OO or ultra-limited OO they're
doing and the way their hashcode() and equals() work with
the convenient collections).
In addition to using Java in a procedural way, they painfully
waste time doing plumbing and fixing the OO/RDB impedance
mismatch.
To me the most "hidden" feature of Java is that it's actually
possible to do OO programming in Java.
But that is something you'll hardly ever find.
Yet anyone who has done OOA->OOD->OOP has hit these pretty
nasty Java limitations: the presence of equals() in the
Object class and the fact that most collections depends
on it is a huge flaw. This is to me one of the biggest
programming language SNAFU of all times.
Once again, people are not doing OO in Java: they're doing
procedural ORM plumbing.
By the great Joshua Bloch:
J.B.: There is no way to extend an instantiable class and add
J.B.: a value component while preserving the equals contract,
J.B.: unless you are willing to forgo the benefits of object-oriented
J.B.: abstraction.
And as he hints, it's impossible to obey the equals contract
unless you forgo the benefits of OO. But once again, most
Java programmers are clueless about OO (they think they do
OO, but they're using Java in a procedural, goto-style way
to do ORM plumbing and they mistake "structure" for "OO").
http://www.artima.com/lejava/articles/equality.html
Of course you can "fix" things manually, but you still
have to deal with the fact that all the collections won't
take your fix into account.
