标记注释与标记接口

2022-09-02 04:40:28

在阅读有关标记接口的信息时,我偶然发现了以下站点: 项目 37:使用标记接口定义类型
根据 Joshua Bloch 的说法,标记接口比标记注释有两个优点。

  1. 标记接口定义由标记类的实例实现的类型;标记批注则不然。此类型的存在允许您在编译时捕获错误,如果使用标记批注,则在运行时之前无法捕获这些错误。

  2. 与标记注释相比,标记界面的另一个优点是可以更精确地定位它们。如果用 target 声明注释类型,它可以应用于任何类或接口。假设您有一个仅适用于特定接口实现的标记。如果将其定义为标记接口,则可以让它扩展它适用的唯一接口,从而保证所有标记的类型也是它适用的唯一接口的子类型。ElementType.TYPE

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

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

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

第二点还提到:

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

难道你不能通过使用元注释@Inherited通过注释来实现这一点吗


答案 1

如何更精确地定位标记界面?

您是对的,两者都可以应用于任何类型。通过“更精确地定位”,作者意味着您可以添加其他限制,以限制标记接口可以应用于哪些特定类型。不可能向批注添加相同的精确限制:如果将批注限制为 ,则它始终可以应用于所有类型。ElementType.TYPE

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

interface Marker extends Foo { }

标记现在只能应用于实现 的类型。Foo

难道你不能通过使用元注释@Inherited通过注释来实现这一点吗

不可以,元注释仅意味着带注释的类的任何子类型都将被视为也具有相同的注释。它不会对批注应用于的类型施加任何限制。@Inherited


答案 2