Lambda 表达式是迄今为止 Java 8 讨论和推广最多的特性。我同意 Lambda 是一个很大的改进,但是我认为其他一些 Java 8 特性由于 Lambda 而显得有点暗淡。在这篇文章中,我想展示另一个很好的 Java 8 特性的一些例子:类型注解
类型注解是一种可以放在任何使用类型的位置上的注释(注:在 Java 8 之前的版本中,只能在声明式前使用注解)。这包括 new 运算符,类型转换, implements 子句和 throws 子句。类型注解加强了分析Java代码的能力,并能够确保更强大的类型检查。
在代码实现上,Java 8为注解增加了两个新的注解类型:
@Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
public @interface Test {
}
TYPE_PARAMETER 允许注解被用在类型变量(注:即泛型)的声明中(比如 MyClass<@Test T>)。
TYPE_USE 允许注解可以被用在任何类型使用的地方。
请注意,在 Java 8 中,以下示例中的注解没有实际作用。Java 8 仅提供定义这些类型的注释的功能,然后由框架和工具开发者来实际上使用它们。所以这是一个将来框架会提供给我们的一个注解集合。以下大多数示例都来自 Type Annotations 规范和各种 Java 8 演示文稿。
带有类型注解的简单类型定义如下所示:
@NotNull String str1 = ...
@Email String str2 = ...
@NotNull @NotBlank String str3 = ...
类型注解也可以用于嵌套类型
Map.@NonNull Entry = ...
用于构造函数
new @Interned MyObject()
new @NonEmpty @Readonly List<String>(myNonEmptyStringSet)
myObject.new @Readonly NestedClass()
类型转换
myString = (@NonNull String) myObject;
query = (@Untainted String) str;
继承
class UnmodifiableList<T> implements @Readonly List<T> { ... }
泛型
List<@Email String> emails = ...
List<@ReadOnly @Localized Message> messages = ...
Graph<@Directional Node> directedGraph = ...
Map<@NonNull String, @NonEmpty List<@Readonly Document>> documents;
包括参数边界和通配符边界
class Folder<F extends @Existing File> { ... }
Collection<? super @Existing File> c = ...
List<@Immutable ? extends Comparable<T>> unchangeable = ...
抛出异常
void monitorTemperature() throws @Critical TemperatureException { ... }
void authenticate() throws @Fatal @Logged AccessDeniedException { ... }
instanceof 语句
boolean isNonNull = myString instanceof @NonNull String;
boolean isNonBlankEmail = myString instanceof @NotBlank @Email String;
以及最后 Java 8 的方法引用
@Vernal Date::getDay
List<@English String>::size
Arrays::<@NonNegative Integer>sort
结论
类型注解是 Java 类型系统的一个有趣的补充。它们可以应用于任何类型的使用,并启用更详细的代码分析。如果您现在要使用类型注解,您应该查看 Checker Framework。