Hello Dan,

Thanks for throwing this together. Very interesting read.

One quick question I have -- why are Enums and Anonymous Classes removed
from the list?

On Wed, Jul 15, 2026 at 6:47 PM Dan Smith <[email protected]> wrote:

> JEP 401 (Value Objects) provides some general advice for migrating
> existing classes to be value classes. It’s a good starting point for anyone
> interested in the topic.
>
> https://openjdk.org/jeps/401#Migrating-to-value-classes
>
> As long as value classes are a preview feature, they can’t generally be
> adopted in the JDK libraries (which are not compiled with
> `--enable-preview`). However, we felt it was important for this JEP to
> provide users with a “starter kit” of some value classes out of the box,
> and to ease into any migration challenges for popular classes, so we
> identified a handful of JDK classes that the JEP can treat as value classes
> when preview features are enabled. (This works thanks to some heroics in
> the build system and deployment tooling.)
>
> It’s worth asking which *other* JDK API classes might want to become value
> classes someday. I explored the question in conjunction with the CSR
> (JDK-8339199), and want to memorialize the experience here, for future
> reference.
>
> Here's a definition of "value candidate" I've used for some analysis:
> - Not an interface, enum, or anonymous class
> - Not a "namespace class" (collection of static members with no other
> interesting code)
> - No mutable fields
> - No synchronized methods
> - Has a value-candidate super (or Object)
> - For our purposes here: public (up to the top level) and exported; final
> or abstract
>
> A separate question that I didn’t explore: what about *implementation*
> classes? We can cast a wider net here, because these can be
> refactored—e.g., made final. Future work, perhaps something that will be
> more driven by targeted interest and high-priority performance
> opportunities.
>
> Applying the above filter to java.base, I find:
> - 1 record
> - 89 concrete stateful classes
> - 5 concrete stateless classes
> - 94 abstract stateless classe
> - 18 abstract stateful classes
>
> Digging into these…
>
>
> ### 1 record
>
> This is java.security.PEM. Most records can be made value classes, this is
> no exception. This is a new API (JEP 538), and has the distinction of being
> the only public record in java.base.
>
> We might consider adding this to our “starter kit” list in a future
> preview release.
>
>
> ### 89 concrete stateful classes
>
> 28 of these are the classes we've already identified for migration.
>
> 8 of these are a bad fit for value classes (5 are an indirectly-mutable
> API; 2 are pseudo-enums; 1 is an empty identity key; 1 is a singleton).
>
> 10 are javax classes I didn't look at.
>
> 4 of these are good value class candidates, but they implement
> Serializable so will need to wait for a migration plan.
> - java.security.KeyPair
> - java.time.temporal.ValueRange
> - java.util.Currency
> - java.util.UUID
>
> That leaves:
> - java.lang: StackWalker, Runtime.Version, ScopedValue.Carrier
> - java.lang.constant: DynamicCallSiteDesc, EnumDesc, VarHandleDesc
> java.lang.invoke: SerializedLambda
> - java.lang.module: ModuleDescriptor components (but not the class itself,
> because it has a cached hashcode); ResolvedModule
> - java.math: MathContext
> - java.net: PasswordAuthentication, UnixDomainSocketAddress,
> InetAddressResolver.LookupPolicy
> - java.nio.charset: CoderResult
> - java.security: 11 classes, including DomainLoadStoreParameter, some
> DrbgParameters and KeyStore nested classes; a few spec classes
> - java.time: some internal classes: DateTimeFormatter, DecimalStyle,
> ZoneOffsetTransition, ZoneOffsetTransitionRule, ZoneRules
> - java.util: HexFormat, RandomGeneratorFactory
>
> From this list, RuntimeVersion and HexFormat are two that struck me as
> simple standalone APIs with private constructors that could readily be
> added to the migration list (although neither has much of a compelling
> performance use case). (I'd also add MathContext, except it has a public
> constructor, so is more of a compatibility risk.) Not coincidentally, these
> are also the few remaining identity classes that claim to be *value-based
> classes*. Like PEM, we could consider adding these to the “starter kit” in
> the future.
>
> Most of the others are a small part of a bigger API. They may be migration
> candidates someday, but I think it would be best to tackle any value
> migration as a focused standalone effort for that API. That effort would
> also include thinking about near-miss candidates due to things like mutable
> fields that cache hashes.
>
>
> ### 5 concrete stateless classes
>
> All singletons, should remain identity classes.
>
> (A singleton doesn’t necessarily *need* identity, but… there’s only one of
> them, so it makes no difference either way.)
>
>
> ### 94 stateless abstract classes + 18 stateful abstract classes
>
> 2 of these are already identified for migration: Number and Record.
>
> 33 are part of a service provider API, which will generally involve
> singletons and is probably best to just exclude from consideration.
>
> 22 represent a mutable API, despite having no mutable fields.
>
> 7 have a private/sealed implementation, so we know would never have value
> subclasses (unless we decide to migrate those subclasses; usually it
> wouldn't make sense).
>
> 23 are in javax packages and I didn't dig into them.
>
> That leaves 25 candidates:
> - java.lang.classfile: CustomAttribute
> - java.lang.constant: DynamicConstantDesc
> - java.lang.module: ModuleReference
> - java.net: 7 abstract classes that probably ought to be interfaces
> - java.nio: Pipe, UserPrincipalLookupService, FileStore, Charset
> - java.security: PKIXCertPathChecker, X509CRLEntry, CertPath, CRL,
> Permission
> - java.text: Format, CollationKey
> - java.util: AbstractCollection, AbstractSet
>
> In the short term, for the “starter kit”, I think it may be worthwhile to
> eventually add AbstractCollection and AbstractSet. (But note that
> AbstractList has a protected mutable field; are we prepared to commit to
> not doing something like that in the future with these other collection
> classes?)
>
> The others could be left to adopt the feature when it’s final, although
> none of them really jump out at me as obvious migration wins. (Not sure how
> many of them even care about public subclassing…)
>
>

Reply via email to