raphw / byte-buddy

Runtime code generation for the Java virtual machine.
https://bytebuddy.net
Apache License 2.0
6.23k stars 804 forks source link

Can ByteBuddy make a non-static field be final? #1634

Closed jimshowalter closed 4 months ago

jimshowalter commented 4 months ago

After using ByteBuddy to add a Set to our entities to track which fields are set, and calling newInstance, the resulting code looks like this:

public class Foo$ByteBuddy$Te6Wfjue extends Foo { private Set<String> _modified$Fields$Tracker;

We then use reflection to set the Set:

public class Foo$ByteBuddy$Te6Wfjue extends Foo { private Set<String> _modified$Fields$Tracker = new HashSet<>();

This is almost conformant with our coding standards, but "final" is missing from the Set.

Is there a way to declare non-static fields final in classes generated by ByteBuddy?

If not, is there a way to set fields to final post-construction?

raphw commented 4 months ago

Sure. Use .subclass(..., ConstructorStrategy.Defaults.NONE).

Byte Buddy will then not create implicit constructors. Instead, you create them explicitly. I assume your proxy has only a default constructor? If so:

MethodCall.invoke(subclass.getConstructor()).onSuper().andThen(MethodCall.invoke(HashSet.class.getConstructor()).setField("_modified$Fields$Tracker")