JDK 16 RFR of JDK-8071961: Add javac lint warning when a default constructor is created
Joe Darcy
joe.darcy at oracle.com
Wed Jul 29 20:10:28 UTC 2020
Hello,
Please review the code changes and CSR for
JDK-8071961: Add javac lint warning when a default constructor is
created
webrev: http://cr.openjdk.java.net/~darcy/8071961.5/
CSR: https://bugs.openjdk.java.net/browse/JDK-8250795
Some background on the design of the warning and broader usage context,
while default constructors can be convenient for informal code, they can
be a bit troublesome for more formal APIs, such as the public classes of
packages in the JDK. One issue is that default constructors do not have
javadoc. Another is that a class that semantically should not be
instantiated, say it is a solely a holder for static constants and
methods, can get instantiated and subclassed. (Subclasssing such a class
is an anti-pattern to allow use short names for the static members,
which is no longer necessary since static imports as of Java SE 5.0.)
Until they were recently fixed, there were about one hundred remaining
default constructors in the JDK API outside of the client libraries (
JDK-8250212 Address reliance on default constructors in the JDK
(umbrella) ). Other occurrences of this issue were sporadically fixed
over the years ( JDK-8236695, JDK-8177153, JDK-8071959, etc.).
In terms of detailed criteria to issue the new warnings, there was the
usual tension in warnings between reducing false positives and false
negatives. For example, warning for *any* default constructor, even in a
throw-away class, would be more annoying than helpful. With some
guidance from the JDK code base, criteria in the current patch are a
default constructor merits a warning if:
* The class is in a named package and the packaged has an unqualified
export from its module AND
* The class is public and, if it is a nested class, all of its lexically
enclosing types are public too.
An unqualified export, where the package is available to use to any
module and not just named ones, was taken to indicate classes in the
package can comprise a "formal API". It would be simple to change this
to an unqualified export, but I wanted to avoid unwanted instances of a
new warning. If a public nested class is a non-public enclosing class,
the nested class is not directly part of the exported API. These
combinations of kinds of exports and nesting are tested in the tests in
the DefaultCtor directory.
The text of the warning message implies what criteria are being used:
# 0: symbol, 1: symbol, 2: symbol
compiler.warn.default-ctor=\
class {0} in exported package {1} of module {2} relies on a
default (implicit) constructor
Once the javac-related changes are reviewed, I'll send a RFR out to
build-dev for the make system updates. Basically modules whose use of
default constructors has not been addressed (java.desktop,
jdk.accessibility, jdk.unsupported.desktop, etc.) have the new warning
disabled.
Thanks,
-Joe
More information about the compiler-dev
mailing list