上一篇学习了 Gradle 的入门知识,Gradle 基于 Groovy,今天学习一下 Groovy 的基础知识,Groovy 是基于 JVM 虚拟机的一种动态语言,语法与 Java 语法类似,Groovy 完全兼容 Java,每个 Gradle 文件都是一个 Groovy 脚本文件,Gradle 文件基于 Groovy 语法,而 Groovy 又兼容 Java,故可以在 Gradle 文件中写 Java 代码,在此基础上增加了很多新特性,如支持闭包、DSL等,可以说 Groovy 是一门非常灵活的动态脚本语言,针对 Gradle 来学习一下 Groovy 的一些基础知识。
字符串
集合
方法
JavaBean
关于闭包
字符串 说一个 Groovy 的特性,在 Groovy 中分号不是必须的,其单引号是双引号都定义的是一个字符串常量,不同之处是单引号是纯粹的字符串常量,不会对该字符串里面的表达式做运算,而使用双引号定义的字符串常量可以使用合法表达式做相关运算,测试代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 task stringTest{ def str1 = "双引号" def str2 = '单引号' println "双引号定义的字符串:" +str1 println "双引号定义的字符串:" +str1.class println "单引号定义的字符串:" +str2 str1 = true ; println "双引号定义的字符串:" +str1.class println "双引号定义的字符串:${str1}" println "双引号定义的字符串:$str1" println '单引号定义的字符串:$str2' }
下面是执行结果,参考如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 PS E:\Gradle\study\Groovy> gradle stringTest > Configure project : 双引号定义的字符串:双引号 双引号定义的字符串:class java.lang.String 单引号定义的字符串:单引号 双引号定义的字符串:class java.lang.Boolean 双引号定义的字符串:true 双引号定义的字符串:true 单引号定义的字符串:$str2 BUILD SUCCESSFUL in 1s
集合 Groovy 中也有集合的概念,主要看一下常用的 List、Map,下面将对 List 和 Map 常用操作进行介绍。
那么如何在 Groovy 中定义 List 呢,Groovy 中的 List 的定义方式类似于 Java 中的数组,具体操作参考下面代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 task list{ def list = [1 ,2 ,3 ,4 ,5 ,6 ]; def weekList = ['星期一' ,'星期二' ,'星期三' ,'星期四' ,'星期五' ,'星期六' ,'星期日' ]; println "list的类型:" +list.class println "weekList的类型:" +weekList.class println '第一个元素:' +list[0 ] println '第二个元素:' +list[1 ] println '最后一个元素:' +list[-1 ] println '倒数第二个元素:' +list[-2 ] println '某个范围内元素:' +list[2. .4 ] weekList.each{ println it } }
下面是上述代码的执行结果,参考如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 PS E:\Gradle\study\Groovy\ListMap> gradle list > Configure project : list的类型:class java.util.ArrayList weekList的类型:class java.util.ArrayList 第一个元素:1 第二个元素:2 最后一个元素:6 倒数第二个元素:5 某个范围内元素:[3, 4, 5] 星期一 星期二 星期三 星期四 星期五 星期六 星期日 BUILD SUCCESSFUL in 2s
那么如何在 Groovy 中定义 Map 呢,Groovy 中的 Map 当然也是键值对,具体定义及操作参考下面代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 task map{ def map = ['name' :'Groovy' , 'age' :10 ]; println "map的类型:" +map.getClass().name; println map.name; println map['name' ]; map.each{ println "Key:${it.key},value:${it.value}" } }
下面是上述代码的执行结果,参考如下:
1 2 3 4 5 6 7 8 9 10 11 PS E:\Gradle\study\Groovy\ListMap> gradle map > Configure project : map的类型:java.util.LinkedHashMap Groovy Groovy Key:name,value:Groovy Key:age,value:10 BUILD SUCCESSFUL in 2s
关于 Groovy 的集合就了解这么多。
方法 Groovy 中的方法和 Java 中的方法类似,只是写法上更加灵活,Groovy 中 return 不是必须的,在不写 return 的时候,Groovy 会将最后一句代码作为该方法的返回值。代码块指的是一段被花括号包围的代码,Groovy 中可将代码块作为一个参数进行传递,可以参考前面关于集合的遍历部分,参考代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 task method{ methodA(1 , 2 ) methodA 1 , 2 def a = methodA 10 , 20 println '获取方法返回的结果:' +a def list = [1 ,2 ,3 ,4 ,5 ]; list.each( { } ) list.each(){ } list.each{ println it } } def methodA(int a, int b){ println a + b a + b }
下面是上述代码参考如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 PS E:\Gradle\study\Groovy\Method> gradle method > Configure project : 3 3 30 获取方法返回的结果:30 1 2 3 4 5 BUILD SUCCESSFUL in 2s
JavaBean Groovy 中的 JavaBean 相较 Java 中的比较灵活,可以直接使用 javaBean.属性的方式获取和修改 JavaBean 的属性值,无需使用相应的 Getter、Setter 方法,直接看代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 task javaBean{ Student student = new Student() student.name = "Groovy" student.age = 10 student.setName("Gradle" ) println "名字是:" +student.name println "年龄是:${student.age}" println "分数是:" +student.score } class Student { private String name private int age public String getScore(){ 100 } public String setName(String name){ this .name = name } public void getName(){ name } }
下面是上述代码的执行结果:
1 2 3 4 5 6 7 8 9 PS E:\Gradle\study\Groovy\JavaBean> gradle javaBean > Configure project : 名字是:Gradle 年龄是:10 分数是:100 BUILD SUCCESSFUL in 2s
闭包 闭包是大多数脚本语言具有的一个特性,如 JavaScript、Groovy 等,闭包就是一个使用花括号包围的代码块,下面来学习 Groovy 中的闭包,主要有两部分:闭包及闭包参数传递和闭包委托。
闭包及其参数传递 下面来看一下如何定义一个闭包以及相关参数的传递,直接上代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 task closure{ mEach{ println it } mEachWithParams{m,n -> println "${m} is ${n}" } } def mEach(closure){ for (int i in 1. .5 ){ closure(i) } } def mEachWithParams(closure){ def map = ["name" :"Groovy" ,"age" :10 ] map.each{ closure(it.key, it.value) } }
上面代码中定义了闭包以及如何进行闭包的参数的传递,当闭包只有一个参数时,默认就是 it,反之闭包有多个参数时,就需要将参数定义出来,具体可参考上述代码,下面是执行结果:
1 2 3 4 5 6 7 8 9 10 11 12 PS E:\Gradle\study\Groovy\Closure> gradle delegate > Configure project : 1 2 3 4 5 name is Groovy age is 10 BUILD SUCCESSFUL in 2s
闭包委托 Groovy 闭包的强大之处在于它支持闭包方法的委托,Groovy 的闭包有三个属性:thisObject、owner、delegate,当在一个闭包中调用定义的方法时,由这三个属性来确定该方法由哪个对象来执行,默认 owner 和 delegate 是相等的,其中 delete 是可以被修改的,Gradle 中闭包的很多功能都是通过修改 delegate 来实现的。下面通过定义一个闭包以及方法,通过打印来说明这三个属性的一些区别:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 task delegate{ new Delegate().test{ println "thisObject:${thisObject.getClass()}" println "owner:${owner.getClass()}" println "delegate:${delegate.getClass()}" println "闭包默认it:" +it.getClass() method() it.method() } } def method(){ println "mththod in root:${this.getClass()}" } class Delegate { def method(){ println "mththod in Delegate:${this.getClass()}" } def test(Closure<Delegate> closure){ closure(this ); } }
下面是上述代码的执行结果,参考如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 PS E:\Gradle\study\Groovy\Closure> gradle delegate > Configure project : thisObject:class build_3ajca04o1rprxygcsq0ajvt7i owner:class build_3ajca04o1rprxygcsq0ajvt7i$_run_closure2 delegate:class build_3ajca04o1rprxygcsq0ajvt7i$_run_closure2 闭包默认it:class Delegate mththod in root:class build_3ajca04o1rprxygcsq0ajvt7i mththod in Delegate:class Delegate BUILD SUCCESSFUL in 2s
当在闭包中调用方法 method() 时,发现是 thisObject 调用了 method() 方法,而不是 owner 或 delegate,说明闭包中优先使用 thisObject 来处理方法的执行,同时可以看到 owner 和 delegate 是一致的,但是 owner 比 delegate 的优先级要高,所以闭包中方法的处理顺序是:thisObject > owner > delegate。
Gradle 中一般会指定 delegate 为当前的 it,这样我们将可以通过 delegate 指定的对象来操作 it 了,下面指定闭包的 delegate 并设置委托优先,让委托的具体对象来执行其方法,下面是测试代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 task student{ configStudent{ println "当前it:${it}" name = "Groovy" age = 10 getInfo() } } class Student { String name int age def getInfo(){ println "name is ${name}, age is ${age}" } } def configStudent(Closure<Student> closure){ Student student = new Student() closure.delegate = student closure.setResolveStrategy(Closure.DELEGATE_FIRST) closure(student) }
下面是上述代码的执行结果,参考如下:
1 2 3 4 5 6 7 8 9 PS E:\Gradle\study\Groovy\Closure> gradle student > Configure project : 当前it:Student@18f6d755 name is Groovy, age is 10 BUILD SUCCESSFUL in 2s
总结 学习 Groovy 的目的还是为了加深对 Gradle 构建工具的理解,上面通过五个方面对 Groovy 有了初步的人认识,后续如果有需要在看 Groovy 的高级用法。