Lombok @Value annotation
This article will cover lombok @Value
annotation in detail, what is its use, its configuration options and overriding its default behaviour with examples.
It will also outline difference between @Value
and @Data annotations.
Lombok
@Value
annotation is applied over a class and it is a shorter replacement of below annotations:@ToString
@EqualsAndHashCode
@AllArgsConstructor
@Getter
@FieldDefaults(makeFinal=true, level=AccessLevel.PRIVATE)
This means that when @Value
is written over a class, it generates
A. toString()
method
B. equals() and hashCode() methods
C. constructor with all fields as arguments, except those that are not assigned a value at declaration.
D. getter methods for all non-static fields.
Besides this, @Value
makes all the non-static fields as private and final, it makes the class as final and does not generate setter method for any of its fields.
In short, it makes the class immutable.
POJO without lombok
Below is a java class having two fields or instance variables, without lombok annotations.
public class User { private String name; private int age; public User(String n, int a) { this.name = n; this.age = a; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public boolean equals(Object o) { // implementation } public int hashCode() { // implementation } public String toString() { // implementation } }
Above class with lombok @Value
annotation will look like
import lombok.Value; @Value public class User { private String name; private int age; }
That is all. You can see how concise the class becomes.
Below is an example program that creates an object of the above class annotated with
@Value
annotation and calls its various methods. public class ValueDemo { public static void main(String[] a) { User user = new User(); user.setName("A"); user.setAge(22); System.out.println("Name is: " +user.getName()); System.out.println("Age is: " +user.getAge()); System.out.println("Hashcode is: " +user.getName()); System.out.println("User as a string: " +user.getName()); } }
Name is: A
Age is: 22
Hashcode is: 4844
User as a string: User(name=A, age=22)
Generating private constructor
It is possible to generate a private constructor for a class, and create a static method with public
access modifier.
This method will return an object of this class instead of exposing the constructor. Generated method will accept all fields as arguments.
To generate private constructor, use staticConstructor
option of @Value
providing it the name of the method to generate. Example,
@Value(staticConstructor = "getInstance") public class User { private String name; private int age; }
Now, you can not create an object of this class with new
. It will be created as
User user = User.getInstance("A", 22);
Remember that this option has nothing to do with Singleton class. Each time getInstance()
is called, a new object will be returned.
@Value configurations
1. Access modifier for all getter/setter methods generated with @Value
will be private
. To set any other access type, you should write explicit @Getter/@Setter
with AccessLevel
option.
2. All fields will be final by default. This can be overridden by using @NonFinal
annotation on specific fields.
3. @Value
also makes the class final
. To override this, use @NonFinal
annotation at class level.
4. equals()
and hashCode()
generated with @Value
use all the fields of the class. To skip any field, use explicit @EqualsAndHashCode.Exclude
over it.
5. Similarly, toString()
generated with @Value
uses all the fields of the class. To skip any field, use explicit @ToString.Exclude
over it.
6. @Value
will not generate a constructor if there is already one present in the class.
7. @Value
will not generate equals()
method, if there is a method with this present in the class.