Valhalla breaks minimal-j framework

Ethan McCue ethan at mccue.dev
Mon Dec 1 20:10:20 UTC 2025


I think I'm understanding. So $ has the same type as the source class, but
each field on it is initialized to something with a unique identity, their
values aren't important, their identity is.

The ways out of this are code generation - make your own $ where everything
is a FieldRef<T> - but that has its own downsides.

  @Minimal
  public class Person {
        public static final Person$ $ = Keys.of(Person$.class);

        @NotEmpty
        public Integer number;

        @Size(100)
        @Searched
        @NotEmpty
        public String name;

        public final Address address = new Address();
  }

It is very possible to make this generate a matching Person$ structure, but
that comes with obvious downsides.

Another option is to generically disallow any value types as fields. This
means custom wrappers for things like Integer, LocalDate, etc. including
custom "zero value" logic to get your unique instance.

  public class Person {
        public static final Person $ = Keys.of(Person.class);

        @NotEmpty
        public minimalj.I32 number;

        @Size(100)
        @Searched
        @NotEmpty
        public String name;

        public final Address address = new Address();
}

Another other option is to start to make use of the instance value, not
just instance identity. Right now all your Integers are 0. Why not have an
AtomicInteger that counts up and use that to give unique Integer instances?


     private static final AtomicInteger i = new AtomicInteger();
     private static final AtomicLong l = new AtomicLong();

    @SuppressWarnings({ "unchecked", "rawtypes" })
    private static Object createKey(Class<?> clazz, String fieldName,
Class<?> declaringClass) {
    if (clazz == String.class) {
        return new String(fieldName);
    } else if (clazz == Integer.class) {
        return new Integer(i.getAndIncrement());
    } else if (clazz == Long.class) {
        return new Long(l.getAndIncrement());

On Mon, Dec 1, 2025 at 2:56 PM Bruno Eberhard <bruno.eberhard at pop.ch> wrote:

> Am 01.12.2025 um 20:37 schrieb Ethan McCue:
> > One more question: How does the code today work around things like the
> > small integer cache?
> It allocates for each field a "new Integer(0)". As long as Integer have
> an identity two of these values are distinguishable and can serve as
> different keys in a IdentityHashMap .
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/valhalla-dev/attachments/20251201/5ea9d23f/attachment.htm>


More information about the valhalla-dev mailing list