我不明白为什么Java注释中没有继承,就像Java类一样。我认为这会很有用。
例如:我想知道一个给定的注释是否是一个验证器。通过继承,我可以反射性地在超类中导航,以了解这个注释是否扩展了ValidatorAnnotation。否则,我怎么才能做到这一点呢?
那么,谁能给我一个这个设计决定的理由呢?
我不明白为什么Java注释中没有继承,就像Java类一样。我认为这会很有用。
例如:我想知道一个给定的注释是否是一个验证器。通过继承,我可以反射性地在超类中导航,以了解这个注释是否扩展了ValidatorAnnotation。否则,我怎么才能做到这一点呢?
那么,谁能给我一个这个设计决定的理由呢?
当前回答
我可能晚了三年才回答这个问题,但我发现它很有趣,因为我发现自己也处于同样的境地。以下是我的看法。您可以将注释作为枚举来查看。它们只提供单向的信息——要么使用,要么失去。
我有一个情况,我想在一个web应用程序中模拟GET, POST, PUT和DELETE。我非常希望有一个“超级”注释,叫做“HTTP_METHOD”。后来我才明白,这无关紧要。好吧,我不得不在HTML表单中使用一个隐藏字段来标识DELETE和PUT(因为POST和GET无论如何都是可用的)。
在服务器端,我寻找一个名为“_method”的隐藏请求参数。如果值是PUT或DELETE,那么它将覆盖相关的HTTP请求方法。话虽如此,我是否需要扩展注释来完成工作并不重要。所有的注释看起来都是一样的,但是它们在服务器端得到了不同的处理。
因此,在您的情况下,不要急于扩展注释。把它们当作“标记”。它们“代表”一些信息,而不一定“操纵”一些信息。
其他回答
关于为什么它不是这样设计的,你可以在JSR 175设计常见问题中找到答案,它说:
为什么不支持注释子类型(一种注释类型扩展另一种注释类型)? 它使注释类型复杂化 系统,并使它更多 “特定工具”很难写。 ... “特定工具”-用于查询的程序 已知的注释类型为任意 外部程序。存根生成器, 例如,就属于这一类。 这些程序读起来是带注释的 类,而无需将它们加载到 虚拟机,但将加载 注解的接口。
所以,是的,我想,原因就是KISS。无论如何,这个问题(以及许多其他问题)似乎正在作为JSR 308的一部分进行研究,您甚至可以找到由Mathias Ricken开发的具有此功能的替代编译器。
我能想到的一件事是有多个注释的可能性。因此,您可以在同一位置添加验证器和更特定的注释。但我可能错了:)
和我有同样的问题。不,你不能。我确实“自律”自己在注释中写属性,以尊重一些标准,所以当你得到注释时,你可以通过它的属性“嗅”出它是什么类型的注释。
在某种意义上,你已经有了它的注释-元注释。如果您用元信息注释注释,这在许多方面等同于扩展一个额外的接口。注释是接口,因此多态性并没有真正发挥作用,而且由于它们本质上是静态的,因此不可能存在运行时动态调度。
在验证器示例中,您可以只在注释上获得带注释的类型,并查看它是否具有验证器元注释。
我所能看到的继承将会有所帮助的唯一用例是,如果您希望能够通过超级类型获得注释,但这将增加一大堆复杂性,因为给定的方法或类型可能有两个这样的注释,这意味着必须返回一个数组,而不仅仅是一个对象。
因此,我认为最终的答案是用例是深奥的,并且使更多的标准用例复杂化,因此不值得这样做。
我可能晚了三年才回答这个问题,但我发现它很有趣,因为我发现自己也处于同样的境地。以下是我的看法。您可以将注释作为枚举来查看。它们只提供单向的信息——要么使用,要么失去。
我有一个情况,我想在一个web应用程序中模拟GET, POST, PUT和DELETE。我非常希望有一个“超级”注释,叫做“HTTP_METHOD”。后来我才明白,这无关紧要。好吧,我不得不在HTML表单中使用一个隐藏字段来标识DELETE和PUT(因为POST和GET无论如何都是可用的)。
在服务器端,我寻找一个名为“_method”的隐藏请求参数。如果值是PUT或DELETE,那么它将覆盖相关的HTTP请求方法。话虽如此,我是否需要扩展注释来完成工作并不重要。所有的注释看起来都是一样的,但是它们在服务器端得到了不同的处理。
因此,在您的情况下,不要急于扩展注释。把它们当作“标记”。它们“代表”一些信息,而不一定“操纵”一些信息。