【IDEA教程】详解 IDEA 注释 @Contract

@Contract
注释用于定义方法必须满足的契约。这使 IDE 可以在调用您已注释的方法的方法中发现问题。您不仅可以将此注释用于注释您自己的代码,还可以用于其他现有库。
注释有@Contract
两个属性 -value
和pure
. 该value
属性包含描述参数和返回值之间的因果关系的子句。
该pure
属性适用于不更改其对象状态而仅返回新值的方法。如果不使用它的返回值,移除它的调用不会影响程序状态或改变语义,除非方法调用抛出异常(异常不被认为是副作用)。
如果一个方法本身不产生副作用,则不应将其标记为纯方法,但它可用于在另一个线程中的事件之间建立发生前的关系,以便在另一个线程中执行的更改可能在当前线程中可见调用此方法后的线程。另一方面,一些同步方法可以标记为纯,因为这里同步的目的是保持集合内部的完整性,而不是等待另一个线程中的事件。允许不影响重要程序语义的“不可见”副作用(例如日志记录)。
Contract是一组描述输入和输出的条款。它们用->
符号分隔:"A -> B"
。这形成了一个Contract,这意味着当您向方法提供 A 时,您将始终得到 B。Contract中的条款必须用;
(分号)符号分隔。例如:
@Contract("_, null -> null") | null 如果它的第二个参数是,则该方法返回null 。 |
---|---|
@Contract("_, null -> null; _, !null -> !null") | null 如果它的第二个参数是,则该方法返回null ,否则返回非空。 |
@Contract("true -> fail") | 一个典型的方法,如果传递给它就会assertFalse() 抛出异常。true |
@Contract("_ -> this") | 该方法总是返回它的限定符(例如StringBuilder.append )。 |
@Contract("null -> fail; _ -> param1") | 如果第一个参数为 null,则该方法抛出异常,否则返回第一个参数(例如,Objects.requireNonNull )。 |
@Contract("!null, _ -> param1; null, !null -> param2; null, null -> fail") | 该方法返回第一个非空参数,如果两个参数都为空(例如,Objects.requireNonNullElse 在 Java 9 中),则抛出异常。 |
定义Contract
- 按Alt+Enter一个方法,然后选择Add method contract或Edit method contract。
- 配置Contract并应用更改。
句法
注释值具有以下@Contract
语法:
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]*
约束是:
_ | 任何值 |
---|---|
null | 空值 |
!null | 值静态证明不为空 |
true | 真正的布尔值 |
false | 假布尔值 |
fail | 如果参数满足参数约束,该方法将引发异常 |
new | 每次执行该方法时,它都会返回一个非空的新对象,该对象与方法执行之前堆中存在的其他对象不同。如果方法是纯的,则新对象不存储在任何字段或数组中,如果不使用方法返回值,新对象将丢失。 |
this | 该方法返回非空this 引用 |
param1 (param2, param3, and so on) | 该方法返回其第一个(第二个、第三个等)参数 |