@Contract 是 JetBrains 在 IntelliJ IDEA 和其他基于 IntelliJ 的 IDE 中提供的一种注解,用于增强代码的可读性和IDE对代码行为的理解。通过使用 @Contract 注解,开发者可以向IDE传达方法的行为信息,比如方法调用的结果如何依赖于其参数值等。这有助于IDE更好地进行静态分析、代码补全以及潜在错误检测。

基本概念

• 作用:@Contract 主要用来指定方法在不同输入条件下的行为模式。

• 位置:通常放置在方法声明之前。

• 效果:帮助IDE理解特定方法的行为逻辑,从而提高代码提示和错误检查的质量。

常见用法

描述方法的返回值

@Contract 注解可以用来描述方法的返回值是否为空或非空。

@Contract("null -> fail")
public void validate(String input) {
    if (input == null) {
        throw new IllegalArgumentException("Input cannot be null");
    }
}
  • null -> null:如果输入为 null,则返回 null
  • !null -> !null:如果输入不为 null,则返回不为 null

描述方法的副作用

@Contract 注解还可以用来描述方法是否会产生副作用。

@Contract("_ -> this")
public StringBuilder append(String str) {
    // 实现省略
    return this;
}
  • _ -> this:表示无论输入是什么,方法都会返回 this,即方法本身。

描述方法的异常行为

@Contract 注解可以用来描述方法是否会抛出异常

@Contract("null -> fail")
public void validate(String input) {
    if (input == null) {
        throw new IllegalArgumentException("Input cannot be null");
    }
}
  • null -> fail:如果输入为 null,则方法会抛出异常。

高级用法

多条件描述

@Contract 注解支持多条件描述,可以使用分号 ; 分隔多个条件。

@Contract("null -> null; !null -> !null; _ -> fail")
public String process(String input) {
    if (input == null) {
        return null;
    }
    if (input.isEmpty()) {
        throw new IllegalArgumentException("Input cannot be empty");
    }
    return input.trim();
}
  • null -> null:如果输入为 null,则返回 null
  • !null -> !null:如果输入不为 null,则返回不为 null
  • _ -> fail:如果输入为空字符串,则抛出异常。

描述多个参数

@Contract 注解可以描述多个参数之间的关系。

@Contract("null, _ -> null; _, null -> null; !null, !null -> !null")
public String concat(String str1, String str2) {
    if (str1 == null || str2 == null) {
        return null;
    }
    return str1 + str2;
}
  • null, _ -> null:如果第一个参数为 null,则返回 null
  • _, null -> null:如果第二个参数为 null,则返回 null
  • !null, !null -> !null:如果两个参数都不为 null,则返回不为 null

示例

import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public class Example {

    @Contract("null -> null; !null -> !null")
    public static @Nullable String trim(@Nullable String input) {
        return input == null ? null : input.trim();
    }

    @Contract("null, _ -> null; _, null -> null; !null, !null -> !null")
    public static @Nullable String concat(@Nullable String str1, @Nullable String str2) {
        if (str1 == null || str2 == null) {
            return null;
        }
        return str1 + str2;
    }

    @Contract("null -> fail")
    public static void validate(@NotNull String input) {
        if (input == null) {
            throw new IllegalArgumentException("Input cannot be null");
        }
    }

    public static void main(String[] args) {
        String result1 = trim("  hello  ");
        String result2 = concat("hello", "world");
        validate("valid input");
    }
}

@Contract 注解主要用于静态分析工具,不会影响实际的运行时行为。

@Contract 注解的描述应当尽量准确,否则可能会导致工具的错误提示。

@Contract 注解通常与 @Nullable@NotNull 等注解一起使用,以进一步增强代码的静态分析能力

文章作者: oohmygosh
版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Blog
Java
喜欢就支持一下吧