Friday, January 31, 2020

Source Code for Effective Java Third Edition Updated to Use Newer Features

Those who have read the Third Edition of Effective Java are likely aware of the source code associated with that book available on GitHub. The jbloch/effective-java-3e-source-code project has 1700+ stars and has been forked nearly 800 times as of this writing. The version of Java featured in the Third Edition of Effective Java is largely JDK 8 with some coverage of JDK 9 (see my earlier post for details on what is covered in this third edition).

Much has been added to the JDK since the publication of the Third Edition of Effective Java and many new releases have arrived with the faster 6-month cadence. Given this, I was particularly interested to see in an amber-spec-experts mailing list post that Rémi Forax has forked jbloch/effective-java-3e-source-code into the GitHub project forax/effective-java-3e-source-code that has "taken the source of Effective Java (3rd Ed) and change them to use var, switch expression, records and the instanceof with the type test pattern."

There are several things that I like about the idea of refreshing examples from Effective Java (Third Edition) to use newer features:

  • Developers can see how to apply effective Java practices using recently released features.
  • Developers can view the differences between the JDK 8/9 versions and the newer versions to see how new constructs replace older constructs and thus gain a better understanding of the newer constructs.
  • It is useful to see some of the changes when deciding whether a particular change to use a newer construct really helps with code readability in a given situation.

The main page for the forked forax/effective-java-3e-source-code (README.md) states, "The source code have been updated to use new constructs available since Java 9, the version used by the 3rd edition." That page then provides bullets on the types of new constructs applied to the source code with links to each new construct's associated JDK Enhancement Proposal (JEP).

As of this writing, Commit 275eef87e4661f7f1edc41f4730cecf7a1096a97 is the main commit of interest. It covers changes to 113 files. I'll call out a few specific changes here to illustrate the types of changes applied (some of which are to apply preferred constructs that were available even before JDK 9):

Conclusion

The ability to view changes to the original source code associated with the Third Edition of Effective Java to accommodate new language constructs is highly useful in terms of learning about the new constructs and how they relate to or replace old constructs and in deciding if the differences are desirable in different situations.

Thursday, January 30, 2020

Recent Valhalla News (Late January 2020)

There has been significant discussion, design, implementation, and testing related to aspects of OpenJDK Project Valhalla in recent months, but a couple things have struck me as particularly interesting over the last few days in terms of Valhalla progress. I briefly summarize those here.

 

Latest on JDK Release Associated with Valhalla

Frédéric Parain has posted "Valhalla EG 20200129" on the valhalla-spec-experts mailing list. This posting constitutes the meeting notes from the Valhalla Expert Group Meeting on 29 January 2020.

There are several interesting discussion points in these Valhalla Expert Group Meeting notes, but none may be more interesting than the answer to the question, "Is there a JDK release targeted for Valhalla?" In response to that question, the notes provide "bullets" that constitute Brian Goetz's response:

  • "too early to say"
  • "VM work is consolidating"
  • "language work still needs significant work before having a road-map"
  • "first release won't have all the features but have to have further additions in mind"

Although there's still much work required for Valhalla, I interpret these comments in a positive manner, especially when compared to responses to a similar question in months and years past.

 

The Future of Integer

The previously referenced Valhalla Expert Group Meeting Notes for 29 January 2020 include this note attributed to Brian Goetz: "Retrofitting of Integer: seemed impossible, but now seems more feasible."

I am not certain of the context of those notes, but reading these notes did make me think of Brian Goetz's discussion in the December 2019 edition of "State of Valhalla" regarding "Integer and friends." In particular, Goetz discusses migrating primitives by changing the "wrapper types (such as Integer and friends) to be interfaces" so that "these interfaces will become the reference projection for the primitives." Or, as Rafael Winterhalter articulates it, "inline class int implements Integer."

Related to this, Goetz wrote in the 6 December 2019 post "Long-awaited State of the Values docs" (I added emphasis):

The other major AHA buried in this document is the realization that the language and VM models need not align 100%. LWorld is the right VM model, but we can use it as a _translation target_ rather than our language model. This allows the primitives to blossom into full inline classes. In the new world, we have inline classes and identity classes, primitives are mostly just inline classes, and the relationship between inlines and identity classes is isomorphic to the current relationship between primitives and classes.

Goetz also discusses "migrating Integer and friends to be inline-friendly" in the post "Superclasses for inline classes."

 

Optional and Integer Will Be Interfaces Instead of Classes

The December 2019 "State of Valhalla" document explains that the Optional class of today will be changed to an interface and that the "wrapper types Integer and friends" will be migrated "to be interfaces, using the same techniques as with migrating Optional."

One downside to this conversion of Optional, Integer, and friends from classes to interfaces is that comparisons of getClass() calls in existing code against these literal types will break (because the classes implementing the interfaces will be returned in the future instead of the interface name). To deal with this, Bug JDK-8237074 ("[lworld] Compiler should emit a warning if code compares the result of getClass() against the class literal for an interface") has been written and addressed in the repo-valhalla repository. Any legacy code that compares the results of a getClass() call to a literal such as java.lang.Integer.class or java.util.Object.class may not work correctly with these changes, but at least there will be a warning.

 

New Edition of "State of Valhalla" Coming Soon?

It sounds possible that there will soon be an updated version of "State of Valhalla." In the 29 January 2020 Vallhalla EG Meeting notes, there are these notes attributed to Brian Goetz:

  • "working on reference projection as an interface or an abstract class"
  • "possible update next week, working on simplification"
  • "would lead to rewrite of 'State of Valhalla'"

 

Interfaces IdentityObject and InlineObject Introduced

In the December 2019 edition of "State of Valhalla," Goetz introduced "new top interfaces" IdentityObject and InlineObject:

To distinguish between inline and identity classes at compile time and runtime, we introduce a pair of restricted interfaces: IdentityObject and InlineObject. Inline classes implicitly implement InlineObject; identity classes implicitly implement IdentityObject.

JDK-8237069 ("[lworld] Introduce and wire-in the new top interfaces") captures the need to write these interfaces and Srikanth Adayapalam has added these new interfaces to repo-valhalla. Adayapalam describes these changes in the post "[LWorld] Definition and wiring in of the new top interface types.," which includes a link to the changeset. This changeset includes the new interfaces IdentityObject and InlineObject. From this new source, we can see that both interfaces are in the java.lang package and both interfaces have no methods defined ("marker" or "tagging" interfaces similar to java.io.Serializable).

The Javadoc for IdentityObject simply states, "A restricted interface implemented by all identity objects." Similarly, the Javadoc for InlineObject simply states, "A restricted interface implemented by all inline objects."

 

Conclusion

Project Valhalla continues to progress and developments in recent months create a feeling that Valhalla design and implementation is solidifying.