<div dir="ltr">On that note, i'd say you have somewhat of a bigger problem w.r.t. enums<br><br><pre style="overflow-wrap: break-word; text-wrap-mode: wrap;"><font color="#000000">     @SuppressWarnings({ "rawtypes", "unchecked", "restriction" })
        public static <T extends Enum<T>> T createEnum(Class<T> clazz, String name) {
                try {
                        Constructor constructorToCall = Enum.class.getDeclaredConstructor(String.class, Integer.TYPE);
                        sun.reflect.ReflectionFactory f = sun.reflect.ReflectionFactory.getReflectionFactory();
                        Constructor c = f.newConstructorForSerialization(clazz, constructorToCall);
                        T e = (T) c.newInstance(name, Integer.MAX_VALUE);
                        return e;
                } catch (Exception x) {
                        throw new RuntimeException(x);
<br></font></pre><pre style="overflow-wrap: break-word; text-wrap-mode: wrap;"><font color="#000000" face="arial, sans-serif">As with all things in jdk.unsupported, I can't help but wonder if there are any VM level invariants you run afoul of by making extra enum instances.

My first stab at #2 is to add something like this

    </font><font color="#000000">record Field<T>(T value) {}<font face="arial, sans-serif">

And start making value types require wrapping. Or instead of providing your own type special case the idiom of "record with single component for adding identity to a field that otherwise wouldn't have it." Or go a little crazy and make a </font>Field<font face="arial, sans-serif"> that distinguishes between when its being used as an actual value holder or as a unique sentinel.

</font></font>public sealed abstract class Field<T> {<br>    public abstract T get();<br><br>    public abstract void set(T value);<br>    <br>    public static <T> Field<T> withInitialValue(T value) {<br>        return new Field.Actual<>(value);<br>    }<br>    <br>    // Maybe encode the path?<br>    public static <T> Field<T> reference(String name) {<br>        return new Ref<>(name);<br>    }<br>    <br>    private static final class Actual<T> extends Field<T> {<br>        private T value;<br>        <br>        Actual(T value) {<br>            this.value = value;<br>        }<br><br>        @Override<br>        public T get() {<br>            return value;<br>        }<br><br>        @Override<br>        public void set(T value) {<br>            this.value = value;<br>        }<br><br>        @Override<br>        public String toString() {<br>            return "Field[" + value + "]";<br>        }<br>    }<br>    <br>    private static final class Ref<T> extends Field<T> {<br>        private String name;<br>        <br>        Ref(String name) {<br>            <a href="http://this.name">this.name</a> = name;<br>        }<br>        <br>        @Override<br>        public T get() {<br>            throw new IllegalStateException("Cannot get a ref");<br>        }<br><br>        @Override<br>        public void set(T value) {<br>            throw new IllegalStateException("Cannot set a ref");<br>        }<br><br>        @Override<br>        public String toString() {<br>            return "Field[ref=#" + name + "]";<br>        }<br>    }<br>}
</pre><pre style="overflow-wrap: break-word; text-wrap-mode: wrap;"><font color="#000000" face="arial, sans-serif">I think it's also worth asking - do you have any usage statistics on your library? (Maven central used to offer download stats, etc.) If you are going to be broken anyways it is probably useful to know the blast radius.</font></pre></div><br><div class="gmail_quote gmail_quote_container"><div dir="ltr" class="gmail_attr">On Mon, Dec 1, 2025 at 3:36 PM Bruno Eberhard <<a href="mailto:bruno.eberhard@pop.ch">bruno.eberhard@pop.ch</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Am 01.12.2025 um 21:10 schrieb Ethan McCue:<br>
> I think I'm understanding. So $ has the same type as the source class, <br>
> but each field on it is initialized to something with a unique identity, <br>
> their values aren't important, their identity is.<br>
<br>
Exactly.<br>
<br>
You pretty much got all my ideas around the problem right.<br>
<br>
1) code generation<br>
<br>
I simply don't like code generation. It makes setup of projects <br>
difficult. It easily breaks because of some wrong paths or forgotten <br>
re-generate. Has to integrate in IDEs.<br>
<br>
2) special field classes<br>
<br>
Using the normal classes is so much more natural. No need to convert.<br>
<br>
3) Use values instead of always "new Integer(0)".<br>
<br>
Yes this works. For almost all supported classes like: String, Integer, <br>
Long, LocalDate, LocalDateTime, LocalTime, BigDecimal.<br>
<br>
For Boolean and Enum I would have to use the second solution.<br>
<br>
<br>
I started with the framework with java 8. Never thought at that time <br>
this would become a problem.<br>
<br>
</blockquote></div>