Groovy 程序结构
1. groovy默认导入的包
import java.lang.*
import java.util.*
import java.io.*
import java.net.*
import groovy.lang.*
import groovy.util.*
import java.math.BigInteger
import java.math.BigDecimal
2. import
2.1 static import
可以像使用静态方法一样使用静态导入的字段或方法
import static Boolean.FALSE
import static String.valueOf;
assert !FALSE //use directly, without Boolean prefix!
println valueOf(FALSE)
与Java的静态导入功能类似,但比Java更动态,只要具有不同的参数类型,它就可以使用与导入方法相同的名称来定义方法:
import static java.lang.String.format
class SomeClass {
String format(Integer i) {
i.toString()
}
static void main(String[] args) {
assert format('String') == 'String' //在Java中编译不会通过
assert new SomeClass().format(Integer.valueOf(1)) == '1'
}
}
2.2 static import 别名
import static Calendar.getInstance as now
assert now().class == Calendar.getInstance().class
2.3 静态 * 导入
导入给定类的所有静态方法
import static java.lang.Math.*
assert sin(0) == 0.0
assert cos(0) == 1.0
我们能够直接访问方法sin和cos,没有Math.前缀
import 别名
as
使用别名来引用一个全称类名
import java.util.Date
import java.sql.Date as SQLDate
Date utilDate = new Date(1000L)
SQLDate sqlDate = new SQLDate(1000L)
assert utilDate instanceof java.util.Date
assert sqlDate instanceof java.sql.Date
3. 脚本与类
3.1 public static void main 与 script
相对于传统的Java类,一个包含main方法的Groovy类可以如下书写:
class Main {
static void main(String... args) {
println 'Groovy world!'
}
}
和Java一样,程序会从这个类的main方法开始执行,这是Groovy代码的一种写法,实际上执行Groovy代码完全可以不需要类或main方法,所以更简单的写法如下:
println 'Groovy world!'
上面两个代码是等效的
一个脚本可以被认为是一个类,而不需要声明它
3.2 Script 类
Groovy编译器会将脚本编译成Java class,上面的例子被编译如下
Main.groovy
import org.codehaus.groovy.runtime.InvokerHelper
class Main extends Script { // 生成的类扩展自Script类
def run() {
println 'Groovy world!' // 脚本的主体会被放在run方法中
}
static void main(String[] args) { // 自动生成main方法
InvokerHelper.runScript(Main, args) //由main方法代理执行run方法
}
}
若没有声明类的名称,生成脚本类的名称与其文件名相同
3.3 方法
脚本中定义的所有方法会放在脚本类中,脚本主体代码被组合到run()方法中,
println 'Hello'
int power(int n) { 2**n }
println "2^6==${power(6)}"
该代码内部转换为:
import org.codehaus.groovy.runtime.InvokerHelper
class Main extends Script {
int power(int n) { 2** n} //将power方法复制到生成的脚本类中
def run() {
println 'Hello'
println "2^6==${power(6)}"
}
static void main(String[] args) {
InvokerHelper.runScript(Main, args)
}
}
脚本被编译成字节码,并保留行号,如果在脚本中抛出异常,堆栈跟踪将显示原始脚本的行号
3.4 变量
脚本中的变量不需要声明类型:
int x = 1
def y = 2
assert x+y == 3
将表现如下:
x = 1
y = 2
assert x+y == 3
两者存在语义上的差异:
像第一个示例,使用类型或 def 声明变量,则它是一个局部变量。它将被放在 run 方法中声明,在脚本主体之外是不可见的。特别地,这样的变量对脚本的其他方法是不可见的
如果没有声明变量的类型或没有使用def,则会进入script Binding。Binding对方法是可见的,如果使用脚本与应用程序交互,并需要在两者之间共享数据,那么Binding是很重要的。
如果希望变量成为脚本类的一个字段而不进入Binding,可以使用 @Field
注释:
import groovy.transform.Field
@Field int x= 3
def power(int n){
x ** n
}
println("3^3 = " + power(3)) // 27