Abstract class with fields implementing ValueObject

Dan Smith daniel.smith at oracle.com
Mon Feb 14 17:19:56 UTC 2022


> On Feb 14, 2022, at 7:23 AM, Frederic Parain <frederic.parain at oracle.com> wrote:
> 
> 
> On 2/13/22 1:05 PM, Dan Smith wrote:
>>> On Feb 12, 2022, at 10:16 PM, Srikanth Adayapalam <srikanth.adayapalam at oracle.com> wrote:
>>> 
>>> I understand Frederic is asking about whether the spec​ inadvertently allows something it should not - Here anyway is javac behavior:
>>> 
>>> Given:
>>> 
>>> abstract class A implements ValueObject {
>>>     int x;
>>> }
>>> 
>>> on compile:
>>> X.java:1: error: The type A attempts to implement the mutually incompatible interfaces ValueObject and IdentityObject
>>> abstract class A implements ValueObject {
>>>          ^
>>> 1 error
>> Yep, this is expected and consistent: javac sees the field and infers the superinterface IdentityObject (per the language rules), then detects the conflict between interfaces.
>> A slightly more interesting variation: declare a simple interface Foo; change to 'A implements Foo'. This compiles fine, inferring A implements IdentityObject. Then separately compile Foo so that it extends ValueObject. No compilation error, but the JVM should detect the IdentityObject/ValueObject conflict when A is loaded.
>> To generate the kind of class files Fred asked about, you'd need to use something other than javac.
> 
> 
> That's not really the point. The JVM cannot rely on what javac generates
> or not, because it has to deal with other class files generators.
> We have to agree on the behavior of the VM based on what is possible in
> the class file, because, at the end, this is what must be implemented.
> 
> The fact that such a class file is useless to the user is almost
> secondary. We just need to know if the VM should accept such class file.
> As long as it doesn't break VM invariants, we are fine accepting it.

Yes, I agree of course. This is an area of the proposed spec where there's an acknowledged uncertainty about what the rules should say, and we'll need to make a final choice and make sure implementations are conforming to that choice.

To resolve the uncertainty, though, we've got to have a design conversation about user expectations, potential impact, etc., and in that context it's relevant how often the class files in question are likely to be produced, how useful the class files in question might be, and so on.

To review where we're at on JVMS:

1) A class file with ACC_PERMITS_VALUE set may implement, or not, ValueObject (directly or indirectly)

2) A class file without ACC_PERMITS_VALUE set, but that declares an <init> method, implicitly implements IdentityObject; if it also implements ValueObject (directly or indirectly), that's an error

3) For a class file without ACC_PERMITS_VALUE set, and without an <init> method:

    3a) Current spec draft says it doesn't implement anything implicitly, and so can implement whatever it wants explicitly

    3b) An alternative spec approach would say it implicitly implements IdentityObject, and so it's an error to also implement ValueObject

My points about "javac doesn't generate it" and "there's precedent for uninstantiable class files" are to argue that (3a) is not a bug. So we can leave it to other factors to decide whether (3a) or (3b) is the right approach.



More information about the valhalla-spec-observers mailing list