@Contract annotation is used for defining a contract that a method must meet. This lets the IDE find problems in methods which call methods that you have annotated. You can use this annotation not only for annotating your own code but also for other existing libraries.
@Contract annotation has two attributes —
value attribute contains clauses describing causal relationship between arguments and the returned value.
pure attribute is intended for methods that do not change the state of their objects, but just return a new value. If its return value is not used, removing its invocation will not affect program state or change the semantics, unless the method call throws an exception (exception is not considered to be a side effect).
A method should not be marked as pure if it does not produce a side effect by itself, but it could be used to establish the happens-before relation between an event in another thread, so that changes performed in another thread might become visible in current thread after invocation of this method. On the other hand, some synchronized methods 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 do not affect important program semantics are allowed.
A contract is a set of clauses that describe an input and an output. They are separated with the
"A -> B". This forms a contract meaning that when you provide A to a method, you will always get B. Clauses in a contract must be separated with the
; (semicolon) symbol. For example:
The method returns
The method returns
The method always returns its qualifier (e.g.
The method throws an exception if the first argument is null, otherwise it returns the first argument (for example,
The method returns the first non-null argument, or throws an exception if both arguments are null (for example,
Define a contract
Press Alt+Enter on a method, and select Add method contract or Edit method contract.
Configure the contract and apply the changes.
@Contract annotation value has the following syntax:
contract ::= (clause ‘;’)* clause
clause ::= args ‘->’ effect
args ::= ((arg ‘,’)* arg )?
arg ::= value-constraint
value-constraint ::= ‘_’ | ‘null’ | ‘!null’ | ‘false’ | ‘true’
effect ::= ‘_’ | ‘null’ | ‘!null’ | ‘false’ | ‘true’ | ‘fail’ | ‘new’ | ‘this’ | ‘param’ number
number ::= [1-9] [0-9]*
The constraints are:
Value statically proved not to be null
True boolean value
False boolean value
The method throws an exception if arguments meet argument constraints
Every time the method is executed, it returns a non-null new object that is distinct from other objects existing in the heap prior to method execution. If the method is pure, the new object is not stored in any field or array and will be lost if method return value is not used.
The method returns non-null
The method returns its first (second, third, and so on) argument