In what order are Java constraints being executed

Viewed 219

I have a Java method in which the method itself is annotated with a constraint (cross-parameter) and the arguments are also annotated with constraints (@NotNull, @NotEmpty etc). Is the method constraint validated after method argument validation or is the order of validation not specified?

1 Answers

Annotations don't inherently do anything. They just mark things. javac itself knows what @Deprecated and @Override and @FunctionalInterface mean, but the effects are always to either do nothing, or to generate a compiler error: These annotations do not cause the compiler to generate any code.

Aside from Project Lombok this is a general principle of annotations, and even Project Lombok is an annotation processor: You have to put lombok on your classpath during a compilation, or nothing happens.

In other words, it is not possible for the @NonNull annotation in your code to generate any null check all on its own. The constraints are applied elsewhere, or by a code generating annotation processor that you explicitly include by putting it on the classpath or passing it along as annotation processor. For example, it IS possible for code you invoke to introspect your method and notice things. Thus, you could for example have:

class Example {
    @NotEmpty String name;
}

and then you can do:

new Example("");

and this won't cause an exception. But you could do:

Validator validator = SomeHypotheticalValidationLibrary.newValidator();
validator.validate(new Example(""));

and then this validator would produce an error stating that the instance you provided fails verification. This is an example of annotations being introspected.

And now to answer your question:

The order in which such constraints are validated depends entirely on the validation library you use to do the validation; out of the box, the annotation itself does not and cannot produce any validation code. You'd have to check the documentation of your validation library, and provide the context within which you are validating.

If you're talking specifically about lombok's @NonNull - lombok scans your code for null checks (either of the form if (x == null) throw new Something(); or of the form Objects.nullCheck or guava's nullcheck). If it finds a nullcheck for an @NonNull annotated parameter, lombok does nothing. If it doesn't, it generates a nullcheck after all your explicit null checks. Lombok stops scanning for nullchecks once it hits a line that is NOT a nullcheck (so, neither an if (x == null) nor a methodInvocation(x, "optional text");). @NonNull is currently the only annotation that causes lombok to generate validation code (there is no @lombok.NotEmpty).

We may be able to give more insights if you explain which annotation processors / validation frameworks you are using.

Related