@Value

Since

@Value was introduced as experimental feature in lombok v0.11.4.

Experimental

Experimental because:

  • Various choices still have to be vetted as being the correct 'least surprise' choice: Should the class be made final by default, etc.
  • Dependent on @Wither which is experimental.
Current status: positive - Currently we feel this feature may move out of experimental status with no or minor changes soon.

Overview

@Value is the immutable variant of @Data; all fields are made private and final by default, and instead of setters, each field gets a so-called 'wither', which is a method that produces a clone with each field having the same value, except for the field you want a new value for. The class itself is also made final by default, because immutability is not something that can be forced onto a subclass. Like @Data, useful toString(), equals() and hashCode() methods are also generated, each field gets a getter method, and a constructor that covers every argument (except final fields that are initialized in the field declaration) is also generated.

In practice, @Value is shorthand for: final @ToString @EqualsAndHashCode @AllArgsConstructor @FieldDefaults(makeFinal = true, level = AccessLevel.PRIVATE) @Getter @Wither.

It is possible to override the final-by-default and private-by-default behaviour using either an explicit access level on a field, or by using the @NonFinal or @PackagePrivate annotations.
It is possible to override any default behaviour for any of the 'parts' that make up @Value by explicitly using that annotation.

With Lombok

@HTML_PRE@

Vanilla Java

@HTML_POST@

Small print

Look for the documentation on the 'parts' of @Value: @ToString, @EqualsAndHashCode, @AllArgsConstructor, @FieldDefaults, @Getter, @Wither.

For classes with generics, it's useful to have a static method which serves as a constructor, because inference of generic parameters via static methods works in java6 and avoids having to use the diamond operator. While you can force this by applying an explicit @AllArgsConstructor annotation, there's also the @Value(staticConstructor="of") feature, which will make the generated all-arguments constructor private, and generates a public static method named of which is a wrapper around this private constructor.