Wednesday, January 17, 2018

What's New in Effective Java's Third Edition?

Ever since hearing about the pending publication of the Third Edition of Effective Java, I've wondered what would be new in it. I assumed that features introduced to Java since Java 6 would be covered and that is indeed the case. However, there are some other changes as well to this third edition of the Java developer classic. In this post, I provide a high-level overview of the topics that are added, changed significantly, or removed in this third edition.

Before listing what I've observed that appears to be new in Effective Java, Third Edition, I need to make the disclaimer statement that I'm likely to miss several changes throughout this book with 12 chapters encompassing 90 items covering well over 350 pages. This post is not intended to provide detailed coverage of the changes in the third edition, but rather is intended as a high-level sampling of the changes and readers are encouraged to borrow or purchase a copy of this Third Edition of Effective Java to access the low-level details.

As expected, there is significant new content in Effective Java, Third Edition related to new features of Java 7, Java 8, and even Java 9.

Java 7

An obvious new item motivated by Java 7 is Item 9 ("Prefer try-with-resources to try-finally") because try-with-resources was introduced with Java 7. Item 32 ("Combine generics and varargs judiciously") is new to the third edition and discusses Java 7-introduced @SafeVarargs annotation (which received some enhancements with Java 9).

Item 8 ("Avoid finalizers and cleaners") has been updated to discuss how to use Java 7-introduced AutoCloseable interface to replace finalizers and cleaners in some of their most common usages. Item 49 ("Check parameters for validity") has been updated to reference Objects.requireNonNull methods introduced with Java 7.

Item 80 ("Prefer executors, tasks, and streams to threads") has "streams" added to its title since the second edition of Effective Java and includes discussion regarding the addition of Fork/Join to the Executor framework in Java 7. Item 59 ("Know and Use the Libraries") discusses the ThreadLocalRandom that was introduced in Java 7.

Item 56 ("Write doc comments for all exposed API elements") discusses the -Xdoclint switch added to javadoc's command-line with JDK 7.

Java 8

Item 21 ("Design interfaces for posterity") covers best practices related to the use of default methods in Java interfaces. The entire Chapter 7 ("Lambdas and Streams") is, as its title describes, related to lambdas and streams introduced with Java 8 and consists of seven items (Item 42 through Item 48) on these functional programming concepts. Item 55 ("Return optionals judiciously") discusses proper use of Java 8-introduced Optional.

Item 1 ("Consider static factory methods instead of constructors") is not a new item in the third edition, but it now discusses static methods in interfaces as supported in Java 8 and enhanced in Java 9. Item 19 ("Design and document for inheritance or else prohibit it") is also not new, but now mentions the Javadoc @implSpec tag that was "added in Java 8 and used heavily in Java 9." Not surprisingly, Item 56 ("Write doc comments for all exposed API elements") also discusses @implSpec use.

Item 50 ("Make defensive copies when needed") does not focus much on it (dates and times are not the focus of that item), but does reference employing Instant instead of Date as of Java 8.

Java 9

The third edition of Effective Java provides less guidance than I anticipated related to modularity (Java Platform Module System), which is arguably the first thing many of us associate with Java 9. Item 15 ("Minimize the accessibility of classes and members") discusses the "two additional, implicit access levels introduced as part of the module system."

Item 8 ("Avoid finalizers and cleaners") was titled simply "Avoid finalizers" in the second edition. The addition of "and cleaners" to this item's title reflects that Java 9 deprecated the finalizer (for reasons I'm all too familiar with) and replaced it with the Cleaner class.

Item 56 ("Write doc comments for all exposed API elements") discusses use of Java 9-introduced Javadoc tag {@index}. Item 59 ("Know and Use the Libraries") discusses the method transferTo(OutputStream) that was added to InputStream with Java 9 in its discussion of why it's important to know what's available in standard libraries.

Item 6 ("Avoid creating unnecessary objects") mentions the deprecation in Java 9 of the Boolean constructor that accepts a single String parameter as an illustration of a point being made in that item. Incidentally, the only other Boolean constructor [Boolean(boolean)] was also deprecated in Java 9.

Effective Java, Third Edition addresses refinements made in Java 9 to static methods in interfaces (Item 1) and to Optional (Item 55). Item 19 also references Java 9's heavy use of @implSpec. Each of these of these three items were highlighted in the "Java 8" section earlier in this post.

Version-independent New General Java Items

There are some new items in Effective Java, Third Edition that lack an obvious connection to a newer version of Java than that covered in the second edition. These include Item 5 ("Prefer dependency injection to hardwiring resources"), Item 25 ("Limit source files to a single top-level class"), and Item 85 ("Prefer alternatives to Java serialization"). I have written a bit more about Item 85 ("Prefer alternatives to Java serialization") in my blog post "Using Google's Protocol Buffers with Java."

A Removed Item and the Appendix

One item from the second edition of Effective Java appears to have been entirely removed. The useful "Appendix" of the third edition is titled "Items Corresponding to the Second Edition" and it indicates that the single-page Item 73 ("Avoid thread groups") from the second edition has been "retired" in the third edition. This Appendix is also structured such that it's easy to identify that the second edition's Item 21 ("Use function objects to represent strategies") is replaced in third edition by Item 42 ("Prefer lambdas to anonymous classes"). Incidentally, there seems to be very few typos in this book in any of its editions, but one typo that does stand out in the third edition is for the row in the Appendix that correlates Item 69 from the second edition with Item 81 of the third edition.

Minor Text Updates

Several items in the third edition of Effective Java have had minor text updates, some of which have significant meaning in the change. These are the most difficult to call out, but I provide one example here. In the second edition, Bloch wrote in parenthetical passing that StringBuffer is "largely obsolete" compared to StringBuilder, but in the third edition this is more strongly worded to state that StringBuffer is the "obsolete predecessor" of StringBuilder. I agree wholeheartedly with that change in text.

Introduction

Eleven chapters in the Effective Java, Third Edition encompass the 90 items constituting "Best Practices for the Java Platform." However, Chapter 1 ("Introduction") is valuable because it associates "key features" from Java 7, Java 8, and Java 9 with the item or items that discuss those key features and the release of Java which introduced those key features. I wish I had paid attention to it earlier, but did not see this handy table on page 1 until after I was mostly finished composing this post. That table would have saved me a lot of time in identifying the items that cover Java 7, Java 8, and Java 9 new features!

The "Introduction" is also worth reading because it lays out the "few fundamental principles" from which "most of the rules in this book derive." I like that Bloch explicitly states in the Introduction, "This book is not for beginners: it assumes that you are already comfortable with Java." There are countless forums and threads online in which people ask for a good book for those new to Java. While I have highly recommended the various editions of Effective Java for intermediate and advanced Java developers, I've always felt that beginning Java developers are better off with a book written for learning Java and then should come to Effective Java when they know core concepts and want to know how to apply those concepts as clearly and simply as possible.

Conclusion

This post has highlighted some of the most significant additions and changes to Effective Java in the Third Edition. However, I only mentioned some of the quick references to Java 7, Java 8, and Java 9 and undoubtedly missed some new and changed text in my summary. The references to a few of the minor changes to items to reflect newer versions of Java have been intended to illustrate how new Java features are woven into multiple items that at first glance don't seem necessarily related to a newer version of Java.

Effective Java is the only book I've ever purchased three copies of, but I have now purchased one copy of each edition over the years and have not been sorry for doing so. The third edition of Effective Java not only covers new features of Java 7, Java 8, and Java 9, but also adds items and updates pre-existing items to reflect Josh Bloch's latest thinking on best practices using the Java programming language.

1 comment:

@DustinMarx said...

The source code that accompanies the Third Edition of "Effective Java" is now available on GitHub.