import groovy.transform.CompileStatic
@CompileStatic
class MyClass {
// this class will be statically compiled...
}
13 静态类型检查和编译
版本 6.2.0
13 静态类型检查和编译
Groovy 是动态语言,默认情况下,Groovy 使用动态分派机制进行方法调用和属性访问。此动态分派机制为该语言提供了很大的灵活性和强大功能。例如,可以在运行时动态向类添加方法,也可以在运行时动态替换现有方法。像这样的特性非常重要,并为该语言提供了强大的功能。然而,有时你可能希望禁用这种动态分派,使用更加静态的分派机制,而 Groovy 提供实现此功能的方式。告诉 Groovy 编译器应该静态编译特定类的方式是使用 groovy.transform.CompileStatic 注释标记类,如下所示。
请参阅有关 Groovy 静态编译的 这些说明,了解有关 CompileStatic
如何工作以及为何可能需要使用它的更多详细信息。
使用 CompileStatic
的一个限制是,当你使用它时,会失去动态调度所提供的强大功能和灵活性。例如,在 Grails 中,你无法从标记为 CompileStatic
的类中调用 GORM 动态查找器,因为编译器无法确认是否存在动态查找器方法,因为它在编译时并不存在。你可能希望利用 Groovy 的静态编译优势,同时不放弃对特定事物(如动态查找器)的动态调度访问,而 grails.compiler.GrailsCompileStatic 可以实现这一目的。GrailsCompileStatic
的行为与 CompileStatic
相同,但它会识别某些 Grails 特性,并允许动态访问这些特定的特性。
13.1 GrailsCompileStatic 注解
GrailsCompileStatic
GrailsCompileStatic
注解可以应用到类或类中的方法。
import grails.compiler.GrailsCompileStatic
@GrailsCompileStatic
class SomeClass {
// all of the code in this class will be statically compiled
def methodOne() {
// ...
}
def methodTwo() {
// ...
}
def methodThree() {
// ...
}
}
import grails.compiler.GrailsCompileStatic
class SomeClass {
// methodOne and methodThree will be statically compiled
// methodTwo will be dynamically compiled
@GrailsCompileStatic
def methodOne() {
// ...
}
def methodTwo() {
// ...
}
@GrailsCompileStatic
def methodThree() {
// ...
}
}
可以通过使用 GrailsCompileStatic
标记一个类,然后通过使用 GrailsCompileStatic
标记具体方法并指定应跳过特定方法的类型检查,来排除特定的方法,如下所示。
import grails.compiler.GrailsCompileStatic
import groovy.transform.TypeCheckingMode
@GrailsCompileStatic
class SomeClass {
// methodOne and methodThree will be statically compiled
// methodTwo will be dynamically compiled
def methodOne() {
// ...
}
@GrailsCompileStatic(TypeCheckingMode.SKIP)
def methodTwo() {
// ...
}
def methodThree() {
// ...
}
}
标记为 GrailsCompileStatic
的代码将全部静态编译,但对于 Grails 特定的交互除外,这些交互无法静态编译,但 GrailsCompileStatic
可以将其识别为允许动态调度。这些交互包括像调用动态查找器,以及在域类中对约束和映射闭包等配置块中的 DSL 代码。
在决定静态编译代码时必须慎重。静态编译有一些好处,但为了享受这些好处,你需要放弃动态调度的功能和灵活性。例如,如果代码是静态编译的,则它无法利用插件可能提供的运行时元编程增强功能。
13.2 GrailsTypeChecked 注解
GrailsTypeChecked
grails.compiler.GrailsTypeChecked 注解与 GrailsCompileStatic
注解非常相似,不同之处在于它只启用静态类型检查,而不是静态编译。这样一来,就能够对编译时在静态下无法验证的表达式提供编译时反馈,同时仍然为该类保留动态调度。
import grails.compiler.GrailsTypeChecked
@GrailsTypeChecked
class SomeClass {
// all of the code in this class will be statically type
// checked and will be dynamically dispatched at runtime
def methodOne() {
// ...
}
def methodTwo() {
// ...
}
def methodThree() {
// ...
}
}