I’m using Lombok to minimize code. Here’s my (contrived) situation in vanilla Java:
public class MyClass { private final int x; private final int sqrt; public MyClass(int x) { this.x = x; sqrt = (int)Math.sqrt(x); } // getters, etc }
I want to use lombok to generate the constructor and getters:
@Getter @RequiredArgsConstructor public class MyClass { private final int x; private int sqrt; }
To get the computation into the class, you might consider an instance block:
{ sqrt = (int)Math.sqrt(x); }
but instance blocks are executed before code in the constructor executes, so x
won’t be initialized yet.
Is there a way to execute sqrt = (int)Math.sqrt(x);
after x
is assigned with the constructor argument, but still use the constructor generated by RequiredArgsConstructor
?
Notes:
- Coding the computation in the getter is not an option (for one, it negates the benefit of using
@Getter
) - This example is a gross simplification of the real life class, which has many
final
fields, and several computed/derived fields, so the boilerplate savings using lombok are considerable - The class is a simple POJO DTO, not a managed bean, so none of the lifecycle javax annotations (e.g.
@PostConstruct
) are of any use
Advertisement
Answer
How about using the lazy
option on @Getter for the computation:
// tested and works OK @Getter(lazy = true) private final int sqrt = (int) Math.sqrt(x);
Note: Calling getSqrt()
works as expected/hoped, firing the computation and setting the “final” field, however accessing the field directly does not invoke the magic – you get the uninitialized value.