After re-reading the State of Valhalla part 3 again [1], I have a couple of questions on constructor handling:
1) The rules for handling ACC_PERMITS_VALUE are different between SoV-2 and SoV-3 in that the language imposes constraints the VM doesn't check. Is this deliberate? SoV-2 says: > The classes they can extend are restricted: Object or abstract classes with > no fields, empty no-arg constructor bodies, no other constructors, no > instance initializers, no synchronized methods, and whose superclasses all > meet this same set of conditions. (Number is an example of such a class.) while SoV-3 says: > Perhaps surprisingly, the JVM does not perform the following checks for > value-superclass candidates, although the source language compiler will > typically do so: > > It should have declared an empty no-argument constructor. (Or if it didn’t, > then the author has somehow consented to having all of the constructors being > skipped by the unnamed factory methods of value subclasses.) "Perhaps surprisingly" is right as I'm surprised =) and not sure I follow why the VM wouldn't enforce the restriction. Is it to avoid having to specify the attributes of that constructor? Which leads me to the next concern: how javac will compile the "empty no-arg constructor bodies" required by SoV-2? Or is the answer we don't care because the VM won't check anyway? 2) What is the rationale behind the return type restrictions on <new> methods? > A <new> method must return the type of its declaring class, or a supertype. .... > While <new> methods must always be static and must return a type consistent > with their class, they can (unlike <init> methods) be declared in any class > file, as far as the JVM is concerned. If I'm reading this correctly, to enforce the first quote we'll need a verifier check to ensure that the declared return type of the <new> method is consistent with the current class or a supertype. But Object is a common supertype, as is ValueObject, so I'm not sure what we're gaining with this restriction as any type is a valid candidate for return from a <new> method as anything can be a subclass of Object. We get a better restriction from the `aconst_init` and `withfield` bytecodes which "can only be executed within the nest of the class that declares the value class being initialized or modified". Do we actually need the restriction on the <new> method or should it be considered non-normative (aka a best practice)? --Dan [1] https://openjdk.java.net/projects/valhalla/design-notes/state-of-valhalla/03-vm-model