B3, default values, and implicit initialization

Dan Smith daniel.smith at oracle.com
Tue Apr 25 18:59:16 UTC 2023


On Apr 24, 2023, at 4:18 PM, Dan Heidinga <heidinga at redhat.com> wrote:

My misgivings around the term "default" are due to having already used it to describe interface methods with a default implementation.  The term has also been used related to the default (initial) value of variables but that has no syntax associated with it.  So precedent supports its use..... a mixed result I guess?  ....And I just found a section in the JLS (8.8.9) that already defines the default constructor for a class.  That's even stronger precedent for reusing the term here given this is a slightly different kind of default constructor.

Forwarding some notes I put together about other uses of "default constructor". This exploration dampened my enthusiasm for trying to unify these different concepts—too many differences, IMHO. I think we're better off with a different keyword (currently trying out "implicit" in the JEP text, but still open for more bikeshedding).

-----

Here are some different "default constructor" concepts that need to coexist in the language, with a list of their properties.

special value class constructor:
- must be explicit
- must be public (maybe can relax this, but I don't want access checks in Arrays.newInstance)
- distinct from an explicit constructor with an empty body (and maybe we allow overloading of both?)
- no execution, can't throw; ignores field/instance initializers
- not subject to final field initialization rule
- gives the class a default instance (*preempting* field initializers!)
- possibly able to opt in to non-atomic instance creation as well
- implies can't have field circularity and can't be an inner class
- TBD how encoded in class files/reflection, there's some sort of special metadata

identity class default constructor:
- implicit, or can be explicitly stated (e.g. for documentation) with an empty body or a 'super()' body
- doesn't get implicitly provided if any other constructor is declared
- compatibility constraint: lots of explicitly stated default constructors in the wild
- has same/greater access than the class
- includes super() call and field/instance initializers, may throw
- no relationship to default instances or non-atomic instance creation
- error if the class has uninitialized final fields
- indistinguishable from any other no-arg constructor by class files/reflection

abstract class "trivial" constructor (if absent, the class is implicitly 'identity'):
- implicit, or can be explicitly stated (e.g. for documentation) with an empty body or a 'super()' body
- doesn't get implicitly provided if any other constructor is declared
- compatibility constraint: lots of explicitly stated "trivial" constructors in the wild
- has same/greater access than the class
- no relationship to default instances or non-atomic instance creation

record class canonical constructor:
I won't dig into it, but this has its own special behavior

(As an aside, there's also "default method", which uses the keyword 'default', and means something totally different.)

So, concretely, could we re-use the special value class constructor syntax in identity classes as a new way to explicitly express the default value constructor? There would be many mismatches:
- it shouldn't give the class a default instance
- it should do super() and run field/instance initializers
- it doesn't imply any field circularity or inner class restriction
- it would (somewhat surprisingly) allow final fields without explicit initialization
- if it's detectable via reflection, we're retroactively saying all legacy classes need to be recompiled to get that capability, and all legacy attempts at explicit default constructors have to be rewritten

Abstract classes still need to recognize legacy attempts at explicit "trivial" constructors. And record classes really want canonical constructors as a distinct concept from allowing a default instance.

My conclusion is I don't think this is a good opportunity for unification. I get the interest in doing so—it is a bit much to have all of these similar concepts floating around, with subtle rules in each case—but I think the need for an explicit opt-in syntax in value classes conflicts with the longstanding "convenience feature" treatment we've used elsewhere, and also the different semantics around code execution are hard to reconcile.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/valhalla-spec-experts/attachments/20230425/29b1e0ca/attachment.htm>


More information about the valhalla-spec-experts mailing list