Groovy 程序结构
1. groovy默认导入的包
import java.lang.*import java.util.*import java.io.*import java.net.*import groovy.lang.*import groovy.util.*import java.math.BigIntegerimport java.math.BigDecimal
2. import
2.1 static import
可以像使用静态方法一样使用静态导入的字段或方法
import static Boolean.FALSEimport 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 nowassert now().class == Calendar.getInstance().class
2.3 静态 * 导入
导入给定类的所有静态方法
import static java.lang.Math.*assert sin(0) == 0.0assert cos(0) == 1.0
我们能够直接访问方法sin和cos,没有Math.前缀
import 别名
as
使用别名来引用一个全称类名
import java.util.Dateimport java.sql.Date as SQLDateDate utilDate = new Date(1000L)SQLDate sqlDate = new SQLDate(1000L)assert utilDate instanceof java.util.Dateassert 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.groovyimport org.codehaus.groovy.runtime.InvokerHelperclass 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.InvokerHelperclass 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 = 1def y = 2assert x+y == 3
将表现如下:
x = 1y = 2assert x+y == 3
两者存在语义上的差异:
像第一个示例,使用类型或 def 声明变量,则它是一个局部变量。它将被放在 run 方法中声明,在脚本主体之外是不可见的。特别地,这样的变量对脚本的其他方法是不可见的
如果没有声明变量的类型或没有使用def,则会进入script Binding。Binding对方法是可见的,如果使用脚本与应用程序交互,并需要在两者之间共享数据,那么Binding是很重要的。
如果希望变量成为脚本类的一个字段而不进入Binding,可以使用 @Field
注释:
import groovy.transform.Field@Field int x= 3def power(int n){ x ** n}println("3^3 = " + power(3)) // 27