IntelliJ IDEA 2016.3 Help

@Contract Annotations

On this page:

Overview

The @Contract annotation brings more safety to your code by defining dependencies between method arguments and return values. This information provides smarter control flow analysis for the source code and helps avoid probable errors.

The @Contract annotation is a powerful and flexible tool that helps make your APIs safer. Furthermore, it's possible to use it not only for annotating your own code but also for other existing libraries.

Once the annotations are configured for the project libraries, IntelliJ IDEA stores information about the annotations in simple XML files, to share with the team via version control.

To enable the annotations in a project, add <IntelliJ IDEA Home>/lib/annotations.jar to the classpath via Project Structure dialog.

The usage of @Contract annotations can be clarified by the following examples:

  • @Contract("_, null -> null") - method returns null if its second argument is null.
  • @Contract("_, null -> null; _, !null -> !null") - 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.

To learn more about @Contract annotations, refer to this page.

Syntax of the @Contract annotation

The @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 ::= value-constraint | ‘fail’

The constraints here are:

  • _ – any value
  • null – null value
  • !null – a value statically proved to be not-null
  • true – true boolean value
  • false – false boolean value
  • fail – the method throws an exception, if the arguments satisfy argument constraints

Attributes of the @Contract annotation

The @Contract annotation has two attributes: value and pure.

The value attribute contains the contract clauses describing causal relations between call arguments and the returned value.

The pure attribute is intended for the methods that do not change the state of their objects, but just return a new value. This attribute may be used as a hint to the "Result of method call ignored" inspection to indicate that the method's return value should be used when called. It is is either false (by default), or true.

Example

Consider the following code:

private static void printSorted(){ List <Integer> sorted = Quicksort.sort(null); if (sorted != null){ System.out.println("Sorted array" + sorted); } } public static <T extends Comparable<T>> List<T> sort(List<T> list){ if(list != null){ List<T> copy = new ArrayList<T>(list); sort(copy); return copy; } else { return null; } }

IntelliJ IDEA doesn't complain, because it doesn't know that a null input yields a null output.

Let's decorate the sort() method with @Contract annotation, specifying that null inputs yield null outputs.

contract_annotation

IntelliJ IDEA immediately recognizes that if statement is extraneous, and reports about the condition that is always false:

false_condition_inspection

Useful hints

IntelliJ IDEA suggests the two intention actions for the methods of the library classes:

  • Add method contract/Edit method contract:
    /help/img/idea/2016.3/contract_annotation_lib.png
  • Both intentions have the possibility to to set pure = true:
    /help/img/idea/2016.3/contract_annotation_lib1.png

See Also

Last modified: 29 November 2016