Abstract class with fields implementing ValueObject
Srikanth Adayapalam
srikanth.adayapalam at oracle.com
Sun Feb 13 05:16:59 UTC 2022
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-retn at openjdk.java.net> on behalf of Dan Smith <daniel.smith at oracle.com>
Sent: 12 February 2022 06:19
To: Frederic Parain <frederic.parain at oracle.com>
Cc: valhalla-spec-experts <valhalla-spec-experts at openjdk.java.net>
Subject: Re: Abstract class with fields implementing ValueObject
> On Feb 9, 2022, at 2:50 PM, Frederic Parain <frederic.parain at 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.)
More information about the valhalla-spec-observers
mailing list