何时/为什么我想使用Groovy的@CompileStatic?

icf*_*ntv 13 groovy annotations

我读过这个: http://docs.groovy-lang.org/latest/html/gapi/groovy/transform/CompileStatic.html,这个: 如果我还使用Java 7,我应该使用Groovy的@CompileStatic吗?并且理解肯定会有性能改进,但是它呢?我不明白到底是@CompileStatic做什么的.

是否有某些类添加@CompileStatic是不费脑子的?我哪里不想要它?

bla*_*rag 16

引用我的答案我应该使用Groovy的@CompileStatic,如果我也使用Java 7:

虽然比正常的Groovy更快,但它只能编译Groovy的一个子集并且行为有点不同.特别是所有动态功能都不再可用.

所有的MOP都将被绕过.构建器通常不起作用,有些扩展了编译器以允许它们通过.此外,在编译时使用静态类型选择方法,而Groovy通常使用运行时可用的方法和运行时类型.这可能导致调用不同的方法.

当然@CompileStatic也提供了一些安全性,因为它是编译器在运行时验证程序的任务.但由于静态信息注定不完整,因此永远不会有100%的安全性.

那么它在哪里是明智的......好吧......例如POGO,因为它们通常不包含所有那么多代码.当然还有通过复制和粘贴从Java移植到Groovy的类.

我想要它在哪里?好吧,目前可能在Android上,因为代码大小有影响,静态编译代码更紧凑.否则我个人很好,完全没有使用@CompileStatic.这更像是品味问题.在某些情况下,紧密循环会有性能提升,但这需要您首先通过分析应用程序进行识别


小智 6

事实证明,这在 AOT 编译 groovy 程序时@CompileStatic 非常有用- 例如使用GraalVM native-image工具。支持native-image MethodHandle仅限于MethodHandle对象是编译时常量的情况。通过使用编译器配置,例如:

import groovy.transform.CompileStatic
withConfig(configuration) {
    ast(CompileStatic)
}
Run Code Online (Sandbox Code Playgroud)

我们可以消除MethodHandle生成的字节码中的动态实例,让GraalVM 提前编译成功。