JetBrains 的@Contract 注解

新手上路,请多包涵

org.jetbrains.annotations.Contract 注释是如何工作的? IntelliJ IDEA 如何支持它?

原文由 spongebob 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 2.9k
2 个回答

首先,我应该说这个注解只是供 IDEA 用来检查可能的错误。 Java 编译器几乎会完全忽略它(它会出现在已编译的工件中,但没有任何效果)。话说回来…

注释的目的是描述方法将遵守的 _契约_,这有助于 IDEA 捕获可能调用此方法的方法中的问题。所讨论的合同是一组以分号分隔的条款,每个条款都描述了一个输入和一个保证发生的输出。因果由 -> 分隔,并描述当您向方法提供 X 时,Y 将 始终 产生的情况。输入被描述为逗号分隔的列表,描述了多个输入的情况。

Possible inputs are _ (any value), null , !null (not-null), false and true ,并且可能的输出将 fail 添加到此列表。

因此,例如, null -> false 意味着,提供了一个 null 输入,一个 false 布尔值是结果。 null -> false; !null -> true expands on this to say that null will always return false and a non- null value will always return true, etc. Finally , null -> fail 表示如果您将空值传递给该方法,该方法将抛出异常。

对于多参数示例, null, !null -> fail 意味着,在双参数方法中,如果第一个参数为 null 而第二个参数不为 null,则将抛出异常,保证。

如果该方法不改变对象的状态,而只是返回一个新值,则应将 pure 设置为true。

原文由 dcsohl 发布,翻译遵循 CC BY-SA 3.0 许可协议

官方文档 指定了注释的所有支持和识别值的 形式语法

通俗地说:

  • 一份合同可以有一个或多个与之相关的条款
  • 子句 总是 [args] -> [effect]
  • Args 是 1 个或多个约束,定义为 any | null | !null | false | true
  • 效果只有一个约束或 fail

让我们来看一个简单的例子——我最喜欢的例子之一是,“无论你传递给这个方法什么,它都会抛出一个异常。”

 @Contract("_-> fail")
public void alwaysBreak(Object o) {
    throw new IllegalArgumentException();
}

在这里,我们使用 _ 或“any”来表示无论我们将什么传递给此方法,我们都会抛出异常。

如果我们撒谎说这个方法将无条件返回 true 怎么办?

 @Contract("_-> true")
public void alwaysBreak(Object o) {
    throw new IllegalArgumentException();
}

IntelliJ 对此提出了一些警告。

在此处输入图像描述

当我们在 void 方法中时,我们说我们要返回一个布尔值,这也(显然)令人沮丧……

在此处输入图像描述


您会发现自己想要使用 @Contract 的主要时间是:

  • 你想保证你返回 true 或 false
  • 您想保证在给定约束条件下返回非空值
  • 您想明确表示可以在给定约束的情况下返回空值
  • 您想明确表示您将在给定约束的情况下抛出异常

这并不是说 @Contract 是完美的;离得很远。它不能在某些上下文中进行非常深入的分析,但是在您的代码库中使用它可以让您的工具免费进行此类分析。

原文由 Makoto 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题