Implicit constructor of the super class of a null restricted value class
John Rose
john.r.rose at oracle.com
Sat Oct 21 19:22:56 UTC 2023
If the super were concrete (non-abstract) then changing the
implicit constructor to public breaks abstraction, so
that would not be something to encourage. I guess that’s
one reason we are focusing on abstract supers.
For an abstract super, having an implicit constructor
allows a lesser abstraction leak. First build a subclass
with an implicit constructor and no fields. Then
instantiate it implicitly. Perhaps you use reflection
on the Class mirror to make an array and then load
the first element, uninitialized. There is your
super-state, exposed by a hostile party, assuming
the subclass was able to initialize enough to
instantiate its implicit instance.
I just remembered that since the implicit constructor
of the sub never actually runs, it never dynamically
resolves its reference to the super. That means that
if the super marked its implicit constructor as
private, there’s no detection of this fact, in the
normal course of object construction. Did we think
about plugging that hole? I guess so, since it would
need the kind of VM load-time check that Dan says
below that he wants to avoid. So mark the super-ctor
public, and forget about the accessibility check to
the super-ctor; it would never fail, so it doesn’t
matter that you don’t check it.
(Alternative model: Should we actually run that
trivial little implicit ctor, once around loading?
The silly thing surely shouldn’t fail, but if it does,
perhaps because of a super-ctor access problem,
then we don’t want the class itself to initialize
further.)
On 21 Oct 2023, at 11:58, Dan Smith wrote:
>> On Oct 21, 2023, at 7:03 AM, forax at univ-mlv.fr wrote:
>>
>> Record is an example, even if we change the constructor of Record to public, an implicit constructor of a super class does not have to be public, being visible to the value class seems enough.
Yes, I’m curious about this too, not just for Record but for
third-party classes we don’t control. Dan’s answer is that those
third parties would have to edit their supers a little anyway.
So why not ask them to mark the implicit constructor public,
along the way? Marking it public avows clearly that there
are will be ways to obtain the initial super-state, so let’s
mark it public. If you can’t mark it public, maybe you
should not allow implicit constructors in subs.
Here’s the access check that would be required, because the
implicit constructor is not actually ever run.
> …
> The trade-off for supporting limited constructor access is that the VM would have to work harder to validate it: as described currently, ImplicitCreation is a boolean flag. If access could be restricted, the access level would have to appear in the ImplicitCreation attribute and be enforced at class loading.
(If we ever go to a design where supers DO NOT need to be
edited to align them with value subs, then we have a different
set of things to worry about. I guess that’s unlikely, although
it is possible in principle. The things that can go wrong with
an unmarked super of a value can be set right, in principle,
by a dynamic check on putfield that refuses to store into
a value sub. That’s what I mean by “in principle”.)
More information about the valhalla-spec-observers
mailing list