我不明白为什么Java注释中没有继承,就像Java类一样。我认为这会很有用。
例如:我想知道一个给定的注释是否是一个验证器。通过继承,我可以反射性地在超类中导航,以了解这个注释是否扩展了ValidatorAnnotation。否则,我怎么才能做到这一点呢?
那么,谁能给我一个这个设计决定的理由呢?
我不明白为什么Java注释中没有继承,就像Java类一样。我认为这会很有用。
例如:我想知道一个给定的注释是否是一个验证器。通过继承,我可以反射性地在超类中导航,以了解这个注释是否扩展了ValidatorAnnotation。否则,我怎么才能做到这一点呢?
那么,谁能给我一个这个设计决定的理由呢?
当前回答
可扩展注释将有效地增加指定和维护另一种类型系统的负担。这将是一个相当独特的类型系统,因此您不能简单地应用OO类型范例。
当你向注释引入多态性和继承时,仔细考虑所有问题(例如,当子注释改变元注释规范(如保留)时会发生什么?)
所有这些增加了什么用例的复杂性?
您想知道一个给定的注释是否属于一个类别?
试试这个:
@Target(ElementType.ANNOTATION_TYPE)
public @interface Category {
String category();
}
@Category(category="validator")
public @interface MyFooBarValidator {
}
如您所见,您可以轻松地使用所提供的功能对注释进行分组和分类。
因此,KISS是不向Java语言引入元类型类型系统的原因。
[注。编辑)
我使用String只是为了演示,并且考虑到一个开放的元注释。对于您自己的给定项目,显然可以使用类别类型的枚举,并为给定的注释指定多个类别(“多重继承”)。请注意,这些值完全是伪造的,仅用于演示目的:
@Target(ElementType.ANNOTATION_TYPE)
public @interface Category {
AnnotationCategory[] category();
}
public enum AnnotationCategory {
GENERAL,
SEMANTICS,
VALIDATION,
ETC
}
@Category(category={AnnotationCategory.GENERAL, AnnotationCategory.SEMANTICS})
public @interface FooBarAnnotation {
}
其他回答
关于为什么它不是这样设计的,你可以在JSR 175设计常见问题中找到答案,它说:
为什么不支持注释子类型(一种注释类型扩展另一种注释类型)? 它使注释类型复杂化 系统,并使它更多 “特定工具”很难写。 ... “特定工具”-用于查询的程序 已知的注释类型为任意 外部程序。存根生成器, 例如,就属于这一类。 这些程序读起来是带注释的 类,而无需将它们加载到 虚拟机,但将加载 注解的接口。
所以,是的,我想,原因就是KISS。无论如何,这个问题(以及许多其他问题)似乎正在作为JSR 308的一部分进行研究,您甚至可以找到由Mathias Ricken开发的具有此功能的替代编译器。
从没想过这个,但是…看来你是对的,注释继承设施没有问题(至少我没有看到它的问题)。
关于你用“验证器”注释的例子-你可以利用“元注释”方法。例如,您将特定的元注释应用到整个注释接口。
我能想到的一件事是有多个注释的可能性。因此,您可以在同一位置添加验证器和更特定的注释。但我可能错了:)
可扩展注释将有效地增加指定和维护另一种类型系统的负担。这将是一个相当独特的类型系统,因此您不能简单地应用OO类型范例。
当你向注释引入多态性和继承时,仔细考虑所有问题(例如,当子注释改变元注释规范(如保留)时会发生什么?)
所有这些增加了什么用例的复杂性?
您想知道一个给定的注释是否属于一个类别?
试试这个:
@Target(ElementType.ANNOTATION_TYPE)
public @interface Category {
String category();
}
@Category(category="validator")
public @interface MyFooBarValidator {
}
如您所见,您可以轻松地使用所提供的功能对注释进行分组和分类。
因此,KISS是不向Java语言引入元类型类型系统的原因。
[注。编辑)
我使用String只是为了演示,并且考虑到一个开放的元注释。对于您自己的给定项目,显然可以使用类别类型的枚举,并为给定的注释指定多个类别(“多重继承”)。请注意,这些值完全是伪造的,仅用于演示目的:
@Target(ElementType.ANNOTATION_TYPE)
public @interface Category {
AnnotationCategory[] category();
}
public enum AnnotationCategory {
GENERAL,
SEMANTICS,
VALIDATION,
ETC
}
@Category(category={AnnotationCategory.GENERAL, AnnotationCategory.SEMANTICS})
public @interface FooBarAnnotation {
}
和我有同样的问题。不,你不能。我确实“自律”自己在注释中写属性,以尊重一些标准,所以当你得到注释时,你可以通过它的属性“嗅”出它是什么类型的注释。