典型的用例是像@Override这样简单的东西,但显然您可以做更多的事情。如果你推动它们的极限,你会得到像Project Lombok这样的东西,尽管我的理解是这是对注解的滥用。那么您到底可以做什么?使用注解在编译时和运行时可以做哪些事情?有什么不能做的呢?
典型的用例是像@Override这样简单的东西,但显然您可以做更多的事情。如果你推动它们的极限,你会得到像Project Lombok这样的东西,尽管我的理解是这是对注解的滥用。那么您到底可以做什么?使用注解在编译时和运行时可以做哪些事情?有什么不能做的呢?
注解属于反射的范畴。仅有注解并不能提供任何功能,你需要在代码中使用它们,或者与诸如动态代理或字节码重写等反射领域的内容一起使用。
反射被认为是非常强大但同时也很危险的东西。
我认为根本问题是:“注解或更普遍地说反射有哪些合法的用途?”
由于反射和安全之间存在紧张关系(破坏类型系统,访问final字段等),因此有两个阵营:那些拥抱元编程的人和那些拥抱安全的人。什么是合法的最终取决于品味和观点。
相关问题:
根据您的评论,似乎您主要关心JSR-269和编译过程中的钩子。我看到JSR-269有两个用例:用于自定义错误/语义检查(例如Override),用于DSL/语言工程。除了用于黑客和实验之外,它是否被广泛使用,我不知道。以下是同事提供的一些很棒的链接:
话虽如此,我认为字节码转换/编译器钩子仍然属于元编程范畴。例如,你可以在编译时像Lombok一样生成getter/setter,或者在运行时使用动态代理来完成这个任务。因此,在我看来,这种二元性意味着我们仍然处在反射领域。
我相信您不能使用注解来洗衣服。
但除此之外,以下是我经验中注解的一些真实限制:
注解是元数据,即关于代码的信息。
通过注解,您可以向注解的使用者(如编译器或运行时代码本身)提供提示和线索。我在一些场合仔细地使用它们,其中它们的存在替代了某些其他布尔比较评估为真的需要,并且提供的属性进一步说明了由于注解的存在实际上需要完成的工作。
关于注解的限制,我不确定如何回答。如果它们解决了实际问题或使您的代码更加优雅,请使用它们,但不要强制使用。
请原谅我可能过于简化事情。
这个问题非常(太?)宽泛,所以我只会给出一个我觉得有趣的例子。JPA 2.0 依赖于注解处理来为实体生成静态元模型类(用于使用 Criteria API 进行类型安全查询)。
org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor
}}(Hibernate 的实现)