jwf*_*arn 36 java metaprogramming
我是C++中静态元编程的粉丝.我知道Java现在有泛型.这是否意味着Java中可能存在静态元编程(即编译时程序执行)?如果是这样,任何人都可以推荐任何可以了解更多信息的好资源吗?
Tho*_*mas 24
不,这是不可能的.泛型不如模板强大.例如,模板参数可以是用户定义的类型,基元类型或值; 但通用模板参数只能是Object其子类型.
编辑:这是一个老答案; 自2011年以来,我们拥有Java 7,它具有可用于此类技巧的Annotations.
Tho*_*uck 11
这个问题已经有将近 10 年的历史了,但我仍然缺少一个答案。这是:是的,但不是因为泛型,注意与 C++ 完全相同。
从 Java 6 开始,我们有了可插入的注解处理 api。静态元编程是(正如您已经在问题中所述)
编译时程序执行
如果您了解元编程,那么您也知道这不是真的,但为了简单起见,我们将使用它。如果您想了解有关元编程的更多信息,请查看此处。
可插入注解处理 api 由编译器在读取 .java 文件之后但在编译器将字节码写入 .class 文件之前调用。(我有一个来源,但我再也找不到它了……也许有人可以在这里帮助我?)。
它允许您在编译时使用纯 java 代码执行逻辑。但是,您正在编码的世界是完全不同的。不是特别糟糕或什么,只是不同。您正在分析的类尚不存在,您正在处理类的元数据。但是编译器运行在JVM中,这意味着您也可以正常创建类和程序。但此外,您可以分析泛型,因为我们的注解处理器在类型擦除之前被调用。
java中静态元编程的主要要点是,您提供元数据(以注释的形式),处理器将能够找到所有带注释的类来处理它们。可以在Baeldung上找到(更简单的)示例,其中形成了一个简单的示例。在我看来,这是一个很好的入门来源。如果你明白这一点,试着自己谷歌一下。那里有多个好的来源,这里要列出很多。还可以看看Google AutoService,它利用注释处理器来消除您创建和维护服务文件的麻烦。如果您想创建类,我建议您查看JavaPoet。
遗憾的是,这个 API 不允许我们操作源代码。但如果你真的想要,你应该看看Project Lombok。他们这样做,但不受支持。
TL;DR:这让我很困惑,为什么我们不像动态那样使用静态元编程,因为它有很多优点。
大多数开发人员看到“动态和静态”并立即得出结论,动态更好。没有错,静态对开发人员有很多负面含义。但在这种情况下(特别是对于 Java),这是完全相反的方式。
动态元编程需要反射,这有一些 主要 缺点。他们有很多。简而言之:性能、安全性和设计。
静态元编程(即注释处理)允许我们与编译器相交,它已经完成了我们试图通过反射完成的大部分事情。我们也可以在这个过程中创建类,这些类再次传递给注解处理器。然后您可以(例如)生成类,这些类可以完成通常必须使用反射完成的工作。此外,我们可以实现“快速失败”系统,因为我们可以通知编译器有关错误、警告等的信息。
尽可能总结和比较:让我们想象一下Spring。Spring 尝试在运行时找到所有带 Component 注释的类(我们可以在编译时使用服务文件来简化),然后生成某些代理类(我们可以在编译时已经完成)并解析 bean 依赖关系(再次,我们已经可以在编译时完成)。Jake Whartons 谈到 Dagger2,他解释了为什么他们转向静态元编程。我还是不明白为什么像Spring这样的大玩家不使用它。
这篇文章很简短,以充分解释这些差异以及为什么静态会更强大。如果你愿意,我目前正在为此做一个演示。如果您有兴趣并会说德语(对不起),您可以查看我的网站。在那里您会看到一个演示文稿,它试图在 45 分钟内解释差异。虽然只有幻灯片。
"静态元编程"是什么意思?是的,C++模板元编程在Java中是不可能的,但它提供了其他方法,比C++中的方法更强大:
没有最好的方法:每种方法都有其优点和缺点.由于JVM的灵活性,Java中的所有这些方法都可以在编译时和运行时使用.
| 归档时间: |
|
| 查看次数: |
9370 次 |
| 最近记录: |