@Documented
@Retention(value=CLASS)
@Target(value={METHOD,CONSTRUCTOR})
public @interface Contract
Method contract has the following syntax:
contract ::= (clause ';')* clause
clause ::= args '->' effect
args ::= ((arg ',')* arg )?
arg ::= value-constraint
value-constraint ::= '_' | 'null' | '!null' | 'false' | 'true'
effect ::= value-constraint | 'fail' | 'this' | 'new' | 'param<N>'
The constraints denote the following:
@Contract("_, null -> null")
- the method returns null if its second argument is null
@Contract("_, null -> null; _, !null -> !null")
- the method returns null if its second argument is null and not-null otherwise
@Contract("true -> fail")
- a typical assertFalse
method which throws an exception if true
is passed to it
@Contract("_ -> this")
- the method always returns its qualifier (e.g. StringBuilder.append(String)
).
@Contract("null -> fail; _ -> param1")
- the method throws an exception if the first argument is null,
otherwise it returns the first argument (e.g. Objects.requireNonNull
).
@Contract("!null, _ -> param1; null, !null -> param2; null, null -> fail")
- the method returns the first non-null argument,
or throws an exception if both arguments are null (e.g. Objects.requireNonNullElse
in Java 9).
Modifier and Type | Optional Element and Description |
---|---|
java.lang.String |
mutates
Contains a specifier which describes which method parameters can be mutated during the method call.
|
boolean |
pure
Specifies that the annotated method has no visible side effects.
|
java.lang.String |
value
Contains the contract clauses describing causal relations between call arguments and the returned value
|
@NonNls public abstract java.lang.String value
public abstract boolean pure
Method should not be marked as pure if it does not produce a side-effect by itself,
but it could be used to establish a happens-before relation between an event in
another thread, so changes performed in another thread might become visible in current thread
after this method invocation. Examples of such methods are Object.wait()
, Thread.join()
or AtomicBoolean.get()
. On the other hand, some synchronized methods like Vector.get(int)
could be marked as pure, because the purpose of synchronization here is to keep the collection internal integrity
rather than to wait for an event in another thread.
"Invisible" side effects (such as logging) that don't affect the "important" program semantics are allowed.
This annotation may be used for more precise data flow analysis, and to check that the method's return value is actually used in the call place.
@NonNls public abstract java.lang.String mutates
The following values are possible:
"this" | Method mutates the receiver object, and doesn't mutates any objects passed as arguments (cannot be applied for static method or constructor) |
"param" | Method mutates the sole argument and doesn't mutate the receiver object (if applicable) |
"param1", "param2", ... | Method mutates the N-th argument |
"this,param1" | Method mutates the receiver and first argument and doesn't mutate any other arguments |