Annotation Type Value.Check
- Enclosing class:
Value
Annotates method that should be invoked internally to validate invariants after instance had
been created, but before returned to a client. Annotated method must be parameter-less
(non-private) method and have a void return type, which also should not throw a checked
exceptions.
@Value.Immutable
public abstract class NumberContainer {
public abstract List nonEmptyNumbers();
@Value.Check
protected void check() {
Preconditions.checkState(!nonEmptyNumbers().isEmpty(),
"'nonEmptyNumbers' should have at least one number");
}
}
// will throw IllegalStateException("'nonEmptyNumbers' should have at least one number")
ImmutableNumberContainer.builder().build();
Precondition checking should not be used to validate against context dependent business rules, but to preserve consistency and guarantee that instances will be usable. Precondition check methods runs when immutable object instantiated and all attributes are initialized, but before returned to caller. Any instance that failed precondition check is unreachable to caller due to runtime exception.
There's additional variant of using this annotation to compute normalized value. This should be
a last-resort solution as implementation might be brittle and error-prone. If you declare
return type of validation method with return type specified as abstract value type, this
validation method will also be able to return substitute instance. Normalized instance should
always be of the immutable implementations type, otherwise ClassCastException will
occur during construction.
Be warned that it's easy introduce unresolvable recursion if normalization is implemented
without
proper or with conflicting checks. Always return this if value do not require
normalization.
@Value.Immutable
public interface Normalize {
int value();
@Value.Check
default Normalize normalize() {
if (value() == Integer.MIN_VALUE) {
return ImmutableNormalize.builder()
.value(0)
.build();
}
if (value() < 0) {
return ImmutableNormalize.builder()
.value(-value())
.build();
}
return this;
}
}
int shouldBePositive2 = ImmutableNormalize.builder()
.value(-2)
.build()
.value();