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

Srikanth

________________________________
From: valhalla-spec-observers <valhalla-spec-observers-r...@openjdk.java.net> 
on behalf of Dan Smith <daniel.sm...@oracle.com>
Sent: 12 February 2022 06:19
To: Frederic Parain <frederic.par...@oracle.com>
Cc: valhalla-spec-experts <valhalla-spec-experts@openjdk.java.net>
Subject: Re: Abstract class with fields implementing ValueObject

> On Feb 9, 2022, at 2:50 PM, Frederic Parain <frederic.par...@oracle.com> 
> wrote:
>
> There's a weird case that seems to be allowed by the Value Objects JVMS draft:
>
> An abstract class can declare non-static fields, which means it won't
> have the ACC_PERMITS_VALUE flag set, but also declare that it implements
> the ValueObject interface.
>
> The combination looks just wrong, because no class can subclass such class:
>  - identity classes are not allowed because of the presence  of
>    the ValueObject interface
>  - value classes are not allowed because of the absence of
>    ACC_PERMITS_VALUE
>
> I've looked for a rule that would prohibit such combination in the
> JVMS draft but couldn't find one.
>
> Did I miss something?

If it doesn't have ACC_PERMITS_VALUE set and it declares an <init> method, the 
class implicitly implements IdentityObject (see 5.3.5). And then there's an 
immediate error, because of the IdentityObject/ValueObject clash.

If it doesn't have ACC_PERMITS_VALUE set and it *doesn't* declare an <init> 
method, it's impossible to instantiate. Then there's a technical question of 
whether an error occurs, but it's not really an interesting use case for 
programmers (and javac would never generate this).

(Relevant discussion on this corner case from the spec changes draft:

An abstract class implements IdentityObject if it declares an instance 
initialization method and does not have its ACC_PERMITS_VALUE flag set; and 
implements ValueObject if the opposite is true (ACC_PERMITS_VALUE, no instance 
initialization method). Instance initialization methods and ACC_PERMITS_VALUE 
represent two channels for subclass instance creation, and this analysis 
determines whether only one channel is "open".

Alternatively, we could ignore instance initialization methods and rely 
entirely on ACC_PERMITS_VALUE. In practice, abstract classes written in the 
Java programming language always have instance initialization methods, so the 
difference in behavior is only relevant to classes produced via other languages 
or tools.)

Reply via email to