标记注释与标记接口

问题描述 投票:0回答:2

在阅读有关标记接口的内容时,我偶然发现了以下站点:第 37 项:使用标记接口定义类型
Joshua Bloch 认为,与 Marker 注释相比,Marker 接口有两个优点。

  1. 标记接口定义了由以下实例实现的类型 标记的类别;标记注释则不然。这个的存在 type 允许您在编译时捕获您无法捕获的错误 如果您使用标记注释,则捕获直到运行时。

  2. 标记接口相对于标记注释的另一个优点是 以便能够更准确地定位他们。如果注释类型是 用目标

    ElementType.TYPE
    声明,它可以应用于任何 类或接口。假设您有一个适用的标记 仅针对特定接口的实现。如果你定义它 作为标记接口,您可以将其扩展为唯一的接口 它适用,保证所有标记的类型也 它适用的唯一接口的子类型。

好的,第一点理解了,但我不确定第二点是否理解正确:

如果使用目标

ElementType.TYPE
声明注释类型,则它可以应用于任何类或接口。

同样,如果我有一个标记接口,那么它也可以应用于任何类或接口。这不是说标记注释和标记接口是同一件事吗? 标记界面如何才能更精准地定位?

第2点也提到:

您可以让[标记接口]扩展其适用的唯一接口,保证所有标记类型也是其适用的唯一接口的子类型。

您是否也可以通过使用

@Inherited
元注释来实现这一点?

java interface annotations
2个回答
14
投票

标记界面如何才能更精准地定位?

您是对的,两者都可以应用于任何类型。通过“更精确地定位”,作者的意思是您可以添加额外的限制,标记接口可以应用于哪些特定类型。不可能向注释添加相同的精确限制:如果注释仅限于

ElementType.TYPE
,那么它始终可以应用于所有类型。

第二点的另一部分详细介绍了如何添加这些限制。如果你有一个标记接口,你可以让它扩展另一个接口(作者称之为唯一接口),如下所示:

interface Marker extends Foo { }

标记现在只能应用于实现

Foo
的类型。

您是否也可以通过使用

@Inherited
元注释来实现这一点?

不,

@Inherited
元注释仅意味着带注释的类的任何子类型都将被视为也具有相同的注释。它对注释可以应用到的类型没有任何限制。


0
投票

例如,其类型使用 @Target(ElementType.FIELD) 进行元注释的注释只能写为字段声明的修饰符。

常量 TYPE_USE 对应于 JLS 4.11 中的 15 个类型上下文,以及两个声明上下文:类型声明(包括注解类型声明)和类型参数声明。

例如,使用 @Target (ElementType.TYPE_USE) 元注释类型的注释可以写在字段的类型上(或者在字段的类型内,如果它是嵌套、参数化或数组类型) ,并且还可以作为类声明的修饰符出现。

这可能会给你一个结论。

© www.soinside.com 2019 - 2024. All rights reserved.