原文首發於微信公衆號:躬行之(jzman-blog),歡迎關注交流!
上一篇學習了 Gradle 的入門知識,Gradle 基於 Groovy,今天學習一下 Groovy 的基礎知識,Groovy 是基於 JVM 虛擬機的一種動態語言,語法與 Java 語法相似,Groovy 徹底兼容 Java,每一個 Gradle 文件都是一個 Groovy 腳本文件,Gradle 文件基於 Groovy 語法,而 Groovy 又兼容 Java,故能夠在 Gradle 文件中寫 Java 代碼,在此基礎上增長了不少新特性,如支持閉包、DSL等,能夠說 Groovy 是一門很是靈活的動態腳本語言,閱讀本文以前能夠先閱讀下面這篇文章:java
下面針對 Gradle 來學習一下 Groovy 的一些基礎知識。數組
說一個 Groovy 的特性,在 Groovy 中分號不是必須的,其單引號是雙引號都定義的是一個字符串常量,不一樣之處是單引號是純粹的字符串常量,不會對該字符串裏面的表達式作運算,而使用雙引號定義的字符串常量可使用合法表達式作相關運算,測試代碼以下:微信
task stringTest{ //使用def關鍵字定義變量, def str1 = "雙引號" def str2 = '單引號' println "雙引號定義的字符串:"+str1 println "雙引號定義的字符串:"+str1.class println "單引號定義的字符串:"+str2 //變量動態變化 str1 = true; println "雙引號定義的字符串:"+str1.class //使用$運算符 println "雙引號定義的字符串:${str1}" //只有一個變量的時候能夠省去中括號 println "雙引號定義的字符串:$str1" //單引號定義的字符串不能使用表達式進行運算 println '單引號定義的字符串:$str2' }
下面是執行結果,參考以下:閉包
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 中的數組,具體操做參考下面代碼:post
task list{ //定義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]//訪問某個範圍內元素,以此類推 //使用each遍歷集合中的元素 weekList.each{ //使用it做爲迭代的元素變量,不能寫錯喔 println it } }
下面是上述代碼的執行結果,參考以下:學習
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 固然也是鍵值對,具體定義及操做參考下面代碼:測試
task map{ //定義Map def map = ['name':'Groovy', 'age':10]; println "map的類型:"+map.getClass().name; //訪問Map裏面的元素 println map.name; println map['name']; //遍歷Map中的元素 map.each{ println "Key:${it.key},value:${it.value}" } }
下面是上述代碼的執行結果,參考以下:gradle
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 的集合就瞭解這麼多。ui
Groovy 中的方法和 Java 中的方法相似,只是寫法上更加靈活,Groovy 中 return 不是必須的,在不寫 return 的時候,Groovy 會將最後一句代碼做爲該方法的返回值。代碼塊指的是一段被花括號包圍的代碼,Groovy 中可將代碼塊做爲一個參數進行傳遞,能夠參考前面關於集合的遍歷部分,參考代碼以下:
task method{ //方法調用 methodA(1, 2) methodA 1, 2 //獲取方法返回的結果 def a = methodA 10, 20 println '獲取方法返回的結果:'+a //代碼塊做爲參數傳遞 def list = [1,2,3,4,5]; list.each( //閉包參數 { // println it } ) //Groovy規定,若是方法的最後一個參數是閉包,能夠直接放到方法外面 list.each(){ // println it } //簡寫方式 list.each{ println it } } //方法的定義 def methodA(int a, int b){ println a + b //Groovy中return語句不是必須的,默認將最後一句代碼的結果做爲返回值 a + b }
下面是上述代碼參考以下:
PS E:\Gradle\study\Groovy\Method> gradle method > Configure project : 3 3 30 獲取方法返回的結果:30 1 2 3 4 5 BUILD SUCCESSFUL in 2s
Groovy 中的 JavaBean 相較 Java 中的比較靈活,能夠直接使用 javaBean.屬性的方式獲取和修改 JavaBean 的屬性值,無需使用相應的 Getter、Setter 方法,直接看代碼:
task javaBean{ //Groovy中定義JavaBean Student student = new Student() student.name = "Groovy" student.age = 10 student.setName("Gradle") println "名字是:"+student.name //不能調用Getter方法獲取值 // println "名字是:"+student.getName println "年齡是:${student.age}" println "分數是:"+student.score } class Student{ private String name private int age //定義的Getter方法所對應的屬性能夠直接調用 public String getScore(){ 100 } //屬性的Getter、Setter方法 public String setName(String name){ this.name = name } public void getName(){ name } }
下面是上述代碼的執行結果:
PS E:\Gradle\study\Groovy\JavaBean> gradle javaBean > Configure project : 名字是:Gradle 年齡是:10 分數是:100 BUILD SUCCESSFUL in 2s
閉包是大多數腳本語言具備的一個特性,如 JavaScript、Groovy 等,閉包就是一個使用花括號包圍的代碼塊,下面來學習 Groovy 中的閉包,主要有兩部分:閉包及閉包參數傳遞和閉包委託。
下面來看一下如何定義一個閉包以及相關參數的傳遞,直接上代碼:
task closure{ //自定義閉包的執行 mEach{ println it } //向閉包傳遞參數 mEachWithParams{m,n -> //m,n ->將閉包的參數和主體區分離開來 println "${m} is ${n}" } } //1.定義一個方法,參數closure用於接收閉包 //2.閉包的執行就是花括號裏面代碼的執行 //3.閉包接收的參數就是閉包參數closure參數中的i,若是是一個參數默認就是it變量 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,反之閉包有多個參數時,就須要將參數定義出來,具體可參考上述代碼,下面是執行結果:
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 來實現的。下面經過定義一個閉包以及方法,經過打印來講明這三個屬性的一些區別:
//閉包的委託 task delegate{ new Delegate().test{ //Groovy閉包的三個屬性:thisObject、owner、delegate println "thisObject:${thisObject.getClass()}" println "owner:${owner.getClass()}" println "delegate:${delegate.getClass()}" //閉包默認it println "閉包默認it:"+it.getClass() //定義的方法,優先使用thisObject來處理 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); } }
下面是上述代碼的執行結果,參考以下:
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 並設置委託優先,讓委託的具體對象來執行其方法,下面是測試代碼:
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() //設置委託對象爲當前建立的Student實例 closure.delegate = student //設置委託模式優先,若是不設置閉包內方法的處理者是thisObject closure.setResolveStrategy(Closure.DELEGATE_FIRST) //設置it變量 closure(student) }
下面是上述代碼的執行結果,參考以下:
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 的高級用法。能夠關注公衆號:躬行之(jzman-blog),一塊兒交流學習。