One measure of a great novel is whether it's worth reading a second time. Similarly, the measure of a great technical book is whether it's worth reading cover to cover when you are already familiar with the topic. As a Java programmer, I might have assumed that reading an entire book on the Java language would not be a worthwhile way to pick up the handful of tidbits that I'd managed never to have acquired. But I would have been wrong.
While this text could be used for someone with a programming background but new to Java, it's structured well enough to solidify and enhance the understanding of someone who's already done this a few years. Specifically, the authors' experience shows when they explain various options for using a feature of the language, explain the comparisons, and then unabashedly advise "do it this way; don't do it the other way". For example, the section on multithreading gives clear and concise explanations as to how create threads and locks and use the "synchronized" keyword, and compelling explains why you'd want to use each of the various options, including the "never" do this cases.
It would have been easy to gloss over "type erasure", as the phrase doesn't imply what it is or why we would care. By including clear opinions and warnings from their own experience, I now understand that generic types in Java are a compile-time construct rather than a full enhancement to the underpinnings of the runtime. The authors explain every consequence of the fact that Java containers actually lose some of their type information after compilation, and therefore why there are arbitrary-seeming limitations and otherwise inexplicable compile-time errors.
While this book is titled as if it would be a solid reference book to let collect dust on your shelf, I found it much better suited for enhancing my mental framework about what Java can and can not do by simply reading it.