After 6 years working as an exotic equity derivatives quant, I have moved into a different role. My new job involves programming in Java, and as the last time I used Java was about a decade ago, it seemed a good idea to get up to date, and I was recommended a couple of books.
Nicking the naming convention (and numbered items structure) from Effective C++ it certainly lives up to its namesake. It's a very good book, although they have rather different aims. Meyers' book essentially tells people 'Yeah, I know C++ is really complex. Don't use it all. Keep it simple and be aware of the funny corner cases.' In comparison, as Java was a simple language, it doesn't tell people to avoid the complex cases.
Indeed, it tells people to use the 'complex' stuff introduced later in Java's lifecycle. All the cool stuff that wasn't around earlier. Generics, the new concurrency framework, and the new containers framework all get big thumbs up. For the most part, the book really concentrates on what good idiomatic Java looks like nowadays. An understanding of what works has evolved over the years, and some of the conventions are illustrated by examples from the Java class libraries that got it wrong. I note that immutability is praised, which feels like a lesson coming out of the functional programming community.
The writing is great. Items are well-explained, and good examples given. Suggestions are not arbitrary, but clearly come from hard-earned years of API design in the real world, on highly visible projects (like several official Java packages). It mentions the importance of writing good technical documentation (JavaDoc etc.), but the whole book is a great example of good technical writing.
Java now is a much better language than it was (although I think C# has the edge in a number of places - but portability is its real Achilles heel for us). There are still a few weak points that annoy me, though. I miss RAII - 'finally' blocks are pretty nasty. More generally, stack-based objects would be nice. And I do miss 'const'. There are plenty of conventions to hack around it (and it was never really well-defined in C++ - you only got shallow, not deep constness), but in the end it feels like that's highlighting a lack in the language. Hey, maybe they'll put an attribute in.
(After a bit of working with the language, it's clear that one of the biggest advantages is in the IDEs - they're not text processors, they're Java processors, and they know an awful lot. I'd heard about them, but using them is something else. Having moved from Haskell and C++, it's really weird to see what happens when you move the intelligence/complexity from the language into the tools! If only they could integrate nicely with emacs...)