Tuesday, May 28, 2019

Google Plus's Demise Impacts Software Development

I didn't think much about it when Google announced in late 2018 "sunsetting the consumer version of Google+." Although I had a Google+ account, I didn't really use it and didn't think I'd miss it. Although I had recognized that the demise of other online resources (Google Code in 2015, Codehaus in 2015, GeoCities in 2009, Google's Knol in 2012, Dr. Dobb's in 2014) would impact my ability as a software developer to access previously published online material, I didn't consider that this could be the case for Google+. Although some of the resources mentioned earlier have left read-only content in place, it appears that Google+ content has already been removed.

The "consumer (personal) version of Google+" was shut down in early April of this year and I ran into my first link that now points only to mention of "Google+ is no longer available for consumer (personal) and brand accounts" rather than to the original content available there. The article I was attempting to read was Jean-Baptiste 'JBQ' Quéru's 2011 post "Dizzying but invisible depth."

The "Dizzying but invisible depth" post is one that that I highly recommend because it describes well how too many layers of abstraction eventually make it difficult or impossible for any one person or even any one team to understand how the entire system works. Here is one paragraph from that post:

Once you start to understand how our modern devices work and how they're created, it's impossible to not be dizzy about the depth of everything that's involved, and to not be in awe about the fact that they work at all, when Murphy's law says that they simply shouldn't possibly work.

After spending a couple of minutes trying to find an alternate version of this post, I decided to spend my time using the Wayback Machine (Internet Archive) to access the post. The Internet Archive Wayback Machine has been useful to me before and it was again this time. I was able to find a snapshot of the "Dizzying but invisible depth" post. I saved a copy of it this time.

The post I referenced here was available on the Internet Archive Wayback Machine and may be available from some other site. However, there may be other software development related resources previously hosted on Google+ that are no longer available. This is a reminder to me of the fragility of online resources. Because of this fragility, I try to save at least the links to articles and posts of interest to me so that I have a chance of accessing the article or post via the Internet Archive Wayback Machine if the original site goes away. In the case of particularly useful posts and articles, I will sometimes go as far as saving it to a PDF for future reference.

Tuesday, May 21, 2019

Explicit No-Arguments Constructor Versus Default Constructor

Most developers new to Java quickly learn that a "default constructor" is implicitly created (by javac) for their Java classes when they don't specify at least one explicit constructor. Section 8.8.9 of the Java Language Specification succinctly states, "If a class contains no constructor declarations, then a default constructor is implicitly declared." That section further describes characteristics of the implicitly created default constructor including it having no parameters, having no throws clause, and invoking the constructor of its super class that similarly accepts no arguments. A Java developer can choose to explicitly implement a no-arguments constructor that is similar to the default constructor (such as accepting no arguments and having no throws clause). In this post, I look at some reasons a developer might decide to implement an explicit no-arguments constructor rather than relying on the implicit default constructor.

Some Reasons to Explicitly Specify No-Arguments Constructors

Preclude Instantiation of a Class

A common reason for implementing an explicit no-arguments constructor is to preclude the default constructor from being implicitly created with public accessibility. This is an unnecessary step if the class has other explicit constructors (that accept parameters) because the presence of any explicit constructor will prevent the implicit default constructor from being generated. However, if there is no other explicit constructor present (such as in a "utility" class with all static methods), the implicit default constructor can be precluded by implement an explicit no-arguments constructor with private access. Section 8.8.10 of the Java Language Specification describes use of all private explicit constructors to prevent instantiation of a class.

Force Class Instantiation via Builder or Static Initialization Factory

Another reason to explicitly implement a private no-arguments constructor is to force instantiation of an object of that class via static initialization factory methods or builders instead of constructors. The first two items of Effective Java (Third Edition) outline advantages of using static initialization factory methods and builders over direct use of constructors.

Multiple Constructors Required Including No-arguments Constructor

An obvious reason for implementing a no-arguments constructor that might be as common or even more common than the reason discussed above is when a no-arguments constructor is needed, but so are constructors that expect arguments. In this case, because of the presence of other constructors expecting arguments, a no-arguments constructor must be explicitly created because a default constructor is never implicitly created for a class that already has one or more explicit constructors.

Document Object Construction with Javadoc

Another reason for explicitly implementing a no-arguments constructor rather than relying on the implicitly created default constructor is to express Javadoc comments on the constructor. This is the stated justification for JDK-8224174 ("java.lang.Number has a default constructor") that is now part of JDK 13 and is also expressed in currently unresolved JDK-8071961 ("Add javac lint warning when a default constructor is created"). Recently written CSR JDK-8224232 ("java.lang.Number has a default constructor") elaborates on this point: "Default constructors are inappropriate for well-documented APIs."

Preference for Explicit Over Implicit

Some developers generally prefer explicit specification over implicit creation. There are several areas in Java in which a choice can be made between explicit specification or the implicit counterpart. Developers might prefer an explicit no-arguments constructor over an implicit constructor if they value the communicative aspect or presumed greater readability of an explicit constructor.

Replacing Default Constructors with Explicit No-Arguments Constructors in the JDK

There are cases in the JDK in which implicit default constructors have been replaced with explicit no-arguments constructors. These include the following:

  • JDK-8071959 ("java.lang.Object uses implicit default constructor"), which was addressed in JDK 9, replaced java.lang.Object's "default constructor" with an explicit no-arguments constructor. Reading the "Description" of this issue made me smile: "When revising some documentation on java.lang.Object (JDK-8071434), it was noted that the class did *not* have an explicit constructor and instead relied on javac to create an implicit default constructor. How embarrassing!"
  • JDK-8177153 ("LambdaMetafactory has default constructor"), which was addressed in JDK 9, replaced an implicit default constructor with an explicit (and private) no-arguments constructor.
  • JDK-8224174 ("java.lang.Number has a default constructor"), which is planned for JDK 13, will replace java.lang.Number's implicit default constructor with an explicit no-arguments constructor.

Potential javac lint Warning Regarding Default Constructors

It is possible that one day javac will have an available lint warning to point out classes with default constructors. JDK-8071961 ("Add javac lint warning when a default constructor is created"), which is not currently targeted for any specific JDK release, states: "JLS section 8.8.9 documents that if a class does not declare at least one constructor, the compiler will generate a constructor by default. While this policy may be convenient, for formal classes it is a poor programming practice, if for no other reason that the default constructor will have no javadoc. Use of a default constructor may be a reasonable javac lint warning."

Conclusion

Relying on default constructors to be created at compile time is definitely convenient, but there are situations in which it may be preferable to explicitly specify a no-arguments constructor even when explicit specification is not required.

Tuesday, May 14, 2019

Java Text Blocks

In the 13 May 2019 post "RFR: Multi-line String Literal (Preview) JEP [EG Draft]" on the OpenJDK amber-spec-experts mailing list, Jim Laskey announced a draft feature JEP named "Text Blocks (Preview)" (JDK-8222530).

Laskey's post opens with (I've added the links), "After some significant tweaks, reopening the JEP for review" and he is referring to the draft JEP that was started after the closing/withdrawing of JEP 326 ["Raw String Literals (Preview)"] (JDK-8196004). Laskey explains the most recent change to the draft JEP, "The most significant change is the renaming to Text Blocks (I'm sure it will devolve over time Text Literals or just Texts.) This is primarily to reflect the two-dimensionality of the new literal, whereas String literals are one-dimensional." This post-"raw string literals" draft JEP previously referred to "multi-line string literals" and now refers to "text blocks."

The draft JEP "Text Blocks (Preview)" provides detailed overview of the proposed preview feature. Its "Summary" section states:

Add text blocks to the Java language. A text block is a multi-line string literal that avoids the need for most escape sequences, automatically formats the string in predictable ways, and gives the developer control over format when desired. This will be a preview language feature.

This is a follow-on effort to explorations begun in JEP 326, Raw String Literals (Preview).

The draft JEP currently lists three "Goals" of the JEP and I've reproduced the first two here:

  1. "Simplify the task of writing Java programs by making it easy to express strings that span several lines of source code, while avoiding escape sequences in common cases."
  2. "Enhance the readability of strings in Java programs that denote code written in non-Java languages."

The "Non-Goals" of this draft JEP are also interesting and the two current non-goals are reproduced here:

  1. "It is not a goal to define a new reference type (distinct from java.lang.String) for the strings expressed by any new construct."
  2. "It is not a goal to define new operators (distinct from +) that take String operands."

The current "Description" of the draft JEP states:

A text block is a new kind of literal in the Java language. It may be used to denote a string anywhere that a string literal may be used, but offers greater expressiveness and less accidental complexity.

A text block consists of zero or more content characters, enclosed by opening and closing delimiters.

The draft JEP describes use of "fat delimiters" ("three double quote characters": ===) in the opening delimiter and closing delimiter that mark the beginning and ending of a "text block." As currently proposed, the text block actually begins on the line following the line terminator of the line with the opening delimiter (which might include spaces). The content of the text block ends with the final character before the closing delimiter.

The draft JEP describes "text block" treatment of some special characters. It states, 'The content may include " characters directly, unlike the characters in a string literal.' It also states that \" and \n are "permitted, but not necessary or recommended" in a text block. There is a section of this draft JEP that shows examples of "ill-formed text blocks."

There are numerous implementation details covered in the draft JEP. These include "compile-time processing" of line terminators ("normalized" to "to LF (\u000A)"), incidental white space (differentiation of "incidental white space from essential white space" and use of String::indent for custom indentation management), and escape sequences ("any escape sequences in the content are interpreted" per Java Language Specification and use of String::translateEscapes for custom escape processing).

Newly named "Java Text Blocks" look well-suited for the stated goals and the current proposal is the result of significant engineering effort. The draft JEP is approachable and worth reading for many details I did not cover here. Because this is still a draft JEP, it has not been proposed as a candidate JEP yet and has not been targeted to any specific Java release.