Evolving instance creation

Dan Smith daniel.smith at oracle.com
Tue Mar 1 20:34:02 UTC 2022


On Mar 1, 2022, at 6:56 AM, Kevin Bourrillion <kevinb at google.com<mailto:kevinb at google.com>> wrote:

The main thing I think CICEs/`new` accomplish is simply to "cross the bridge". Constructors are void and non-static; yet somehow we need to call them as if they're static and non-void! `new` gets us across that gap. This seems to me like a special-snowflake problem that `new` is custom built to address, and I would hope we keep it.

Okay. So support for 'new Point()' (1) over just 'Point()' (3) on the basis that constructor declarations need special magic to enter the context where the constructor body lives. So as long as we're declaring value class constructors in the same way as identity class constructors, it makes sense for both to have the same invocation syntax, and for that syntax to be somehow different from a method invocation.

I suppose (3) envisions this magic happening invisibly, as part of the instantiation API provided by the class—there's some magic under the covers where a bridge/factory-like entity gets invoked and sets up the context for the constructor body. But I agree that it's probably better not to have to appeal to something invisible when people are already used to the magic being explicit.

A couple more minor points about the factories idea:

A related, possibly-overlapping new Java feature idea (not concretely proposed, but something the language might want in the future) is the declaration of canonical factory methods in a class, which intentionally *don't* promise unique instances (for example, they might implement interning). These factories would be like constructors in that they wouldn't have a unique method name, but otherwise would behave like ad hoc static factory methods—take some arguments, use them to create/locate an appropriate instance, return it.

Can you clarify what these offer that static methods don't already provide? The two weaknesses I'm aware of with static factory methods are (1) subclasses still need a constructor to call and (2) often you don't really want the burden of naming them, you just want them to look like the obvious standard creation path. It sounds like this addresses (2) but not (1), and I assume also addresses some (3).

A couple of things:

- If it's canonical, everybody knows where to find it. APIs like reflection and tools like serialization can create instances through a universally-recognized mechanism (but one that is more flexible than constructors).

- In a similar vein, if JVMS can count on instantiation being supported by a canonical method name, then this approach can subsume existing uses of 'new/dup/<init>', which are a major source of complexity. This is a very long game, but the idea is that eventually the old mechanism (specifically, use of the 'new' bytecode outside of the class being instantiated) could be deprecated.

(2) 'new Foo()' as a general-purpose creation tool

In this approach, 'new Foo()' is the use-site syntax for *both* factory and constructor invocation. Factories and constructors live in the same overload resolution "namespace", and all will be considered by the use site.

It sounds to me like these factories would be static, so `new` would not be required by the "cross the bridge" interpretation given above.

Right. This approach gives up the use-site/declaration-site alignment, instead interpreting 'new' as "make me one of these, using whatever mechanism the class provides".


More information about the valhalla-spec-observers mailing list