Static Type Checking and Static Compilation
23.1 @TypeChecked
Catches typos, missing methods, and wrong types at compile time. It keeps dynamic dispatch at runtime.
import groovy.transform.TypeChecked
@TypeChecked
class Calculator {
int add(int a, int b) { a + b }
void test() {
// add("1", 2) // compile error: cannot find matching method
// def x = undefinedVar // compile error
String s = "text"
// s.nonExistentMethod() // compile error
}
}23.2 @CompileStatic
Type checking plus static method dispatch (no MOP). It generates bytecode similar to Java's. It's much faster for CPU-bound code.
Trade-off: runtime metaprogramming (metaClass changes, methodMissing) is ignored for statically compiled call sites.
@CompileDynamic / @TypeChecked(TypeCheckingMode.SKIP) opt specific methods back out.
Apply globally with a compiler configuration script: withConfig(configuration) { ast(CompileStatic) } + groovyc --configscript config.groovy.
import groovy.transform.CompileStatic
@CompileStatic
class FastMath {
static long fib(int n) { n < 2 ? n : fib(n - 1) + fib(n - 2) } // Java-like speed
}23.3 Flow Typing and Inference
@groovy.transform.TypeChecked
def flow() {
def o = "string"
o = o.toUpperCase() // inferred String
Object x = "abc"
if (x instanceof String) {
println x.length() // smart cast after instanceof
}
}23.4 Closure Parameter Types: @ClosureParams and @DelegatesTo
import groovy.transform.stc.*
@groovy.transform.CompileStatic
void eachUser(List<String> users, @ClosureParams(value = SimpleType, options = "java.lang.String") Closure c) {
users.each(c)
}
class EmailSpec { String to; String subject; void to(String t) { to = t } }
void email(@DelegatesTo(value = EmailSpec, strategy = Closure.DELEGATE_FIRST) Closure cl) {
def spec = new EmailSpec()
cl.delegate = spec
cl.resolveStrategy = Closure.DELEGATE_FIRST
cl()
}
email { to "[email protected]"; subject = "Hi" } // the IDE and type checker know the delegate type23.5 Type Checking Extensions
Custom scripts that teach the type checker about DSLs (@TypeChecked(extensions = 'MyExtension.groovy')). Groovy 4 added optional groovy-typecheckers (e.g., a regex checker and format string checker).