5

Java 8 在 JSR308 中引入了类型注解。根据 Java 语言规范

类型注释可以在任何使用类型的地方使用,例如声明、泛型参数、强制转换等。

我对Java比较陌生,Java 8是我使用的第一个Java版本,所以我不熟悉非“类型注释”,即声明注释。

声明注解与类型注解有何不同?我想知道,因为我一直在手册中听到它们,看起来“类型注释”是“声明注释”的超集。

4

2 回答 2

3

Java 中仍然存在类型注解和声明注解,它们是不同的且不重叠的。

可以在任何使用类型时编写类型注释。它在概念上创建了一种新的、更具体的类型。也就是说,它描述了该类型所代表的值。

例如,int类型包含值 ..., -2, -1, 0, 1, 2, ...
@Positive int类型包含值 1, 2, ...
因此,@Positive int是 的子类型int

声明注释可以写在任何声明类、方法或变量)上。它描述了被声明的东西,但不描述运行时值。以下是声明注释的示例:

@Deprecated
class MyClass { ... }

说程序员不应该使用MyClass.

@Override
void myMethod() { ... }

表示myMethod覆盖超类或接口中的声明。

@SuppressWarnings(...)
int myField = INITIALIZATION-EXPRESSION;

表示编译器不应发出有关初始化表达式中代码的警告。

以下是同时使用声明注释和类型注释的示例:

@Override
@NonNull String myMethod() { ... }

@GuardedBy("myLock")
@Regex String myField;

请注意,类型注释描述了值,而声明注释说明了该字段的方法或使用。

作为风格问题,声明注释写在自己的行上,类型注释直接写在类型之前,在同一行。

于 2018-05-02T13:05:38.160 回答
2

现在大多数注解都是声明注解,例如@Override

class Foo implements Runnable {
    @Override // applies to the declaration of Foo.run()
    public void run() {
    }
}

类型注释将可能的注释目标扩展到使用声明类型(强制转换、类型参数等)。类型注解可以出现声明中,但类型注解不是声明注解的超集。例如,@Override绝不是类型注释。

例如,在模棱两可的情况下@Foo int x;JLS §9.7.4 概述了被认为是被注释的声明还是类型的具体规则。在某些情况下,它甚至被视为两者兼而有之。

以下是一些明确的类型注释示例:

// cast
String str = (@Foo String) take();
// type argument
List<@Foo String> list = new ArrayList<>();

我想我还可以补充一点,目前类型注释的问题是没有官方 API 可以让注释处理器(基本上是编译器插件)对它们做任何有意义的事情。因此,类型注释通常仅由第三方工具使用,例如 Lombok 和 Eclipse 编译器。

于 2018-05-01T15:49:02.080 回答