#968·javapoet

Construct transparent objects

Author: robertvazanCreated May 21, 2023Updated Feb 10, 2024

It would be neat to have CodeBlock API that recursively emits code to construct transparent values (records, arrays, collections, enums, primitives, strings, and null, perhaps others).

For now, I have a utility method that does this for the types I care about:

java
public class JavaPoetEx {
    public static CodeBlock construct(Object object) {
        if (object == null)
            return CodeBlock.of("null");
        if (object instanceof Integer || object instanceof Long || object instanceof Double || object instanceof Float)
            return CodeBlock.of("$L", object);
        if (object instanceof Enum<?> en)
            return CodeBlock.of("$T.$N", en.getClass(), en.name());
        if (object instanceof Record record) {
            return CodeBlock.of("new $T($L)", record.getClass(), StreamEx.of(record.getClass().getDeclaredFields())
                .filter(f -> !Modifier.isStatic(f.getModifiers()))
                .map(Exceptions.sneak().function(f -> record.getClass().getMethod(f.getName()).invoke(record)))
                .map(JavaPoetEx::construct)
                .collect(CodeBlock.joining(", ")));
        }
        throw new IllegalArgumentException();
    }
}

This could be implemented as a new parameter type (perhaps $V for value) that generalizes $L and $S. It would sort of serialize values as Java code the same way JSON serializes values as JavaScript code.