How much of this is already covered by https://openjdk.java.net/jeps/390 ?

On Apr 25, 2022, at 11:12 PM, Kevin Bourrillion 
<kev...@google.com<mailto:kev...@google.com>> wrote:

So I want to make my class identityless. But -- whoops! -- I released it years 
ago and it has lots of usages. And though I've labeled it as "value-based", any 
number of these callers are depending on its identity in some way or other.

I'd like to put -- let's say an annotation on my class, like 
`@_FutureNonIdentityClass` or whatever, with the following effects:

* I get a warning if I'm breaking any of the rules of identityless classes, 
like if I have a non-final field.
* Use sites get a warning if they do _anything_ identity-dependent with it (==, 
identity hc, synchronization, ...?)

This would leave me in a good position to add the real identity-forsaking 
keyword later (at which time the annotation becomes redundant and should cause 
a warning until it's removed).

We can address all this in Error Prone, but I'm not sure it should be left to 
that, partly because a bunch of JDK value-based types need this same treatment 
themselves (apparently only the synchronization warning has been rolled out so 
far?).

Could we get this supported in javac itself? The best thing would be to roll it 
out in an even earlier release than bucket 2 types themselves... the sooner the 
better (maybe we could help?).

I think the annotation could be relegated to some one-off module so it doesn't 
pollute the beautiful jdk.base forever.

~~~

One of the things this means is that people should stop using `==` on these 
value-based classes.

And that is really really good, because what we are planning to do to `==` 
is... really really bad.  Don't misread me: if compatibility is sacrosanct then 
it is probably the least-bad thing we can do! But honestly, it's bad, because 
it's not a behavior that anyone ever *actually wants* -- unless they just 
happen to have no fields of reference types at all. But the fact that it does 
work in that case just makes the whole thing worse, because code like that will 
be a ticking time bomb waiting to do the wrong thing as soon as one 
reference-type field is added at any nested level below that point.

What if we give users support for their migration path, so there *are no* 
usages of `==` that need to remain compatible for these types? Then we could 
make `==` *not do anything* at all for bucket-2 classes.

This approach could save us from a lot of pain (longstanding pain and new pain) 
for int and Integer and friends too.

I think Java's historical priority of "compatibility at all costs" has been 
something of an illusion; it still leaves us high and dry when *we* want to 
adopt new features as *we* end up having to make incompatible changes to do it. 
But if we always gave proper support to users' migration  scenarios then we 
wouldn't always *need* the absolute compatibility at the language level.

~~~

(Just to try to move the old overton window, what I really think we should do 
is go further and deprecate `==` entirely, introducing 
`System.identityEquals(a, b)` (or maybe `===`) which would only work for 
identity types. Then in time `==` could be reintroduced as a synonym for 
`Object.equals()` and everyone would be happy and write shiny bug-free 
programs.... I know this would be a large deal. Sometime I will have to write 
at length about just how bad the problem of identity-equality overuse/abuse has 
been.)

--
Kevin Bourrillion | Java Librarian | Google, Inc. | 
kev...@google.com<mailto:kev...@google.com>

Reply via email to