您好,登錄后才能下訂單哦!
Gradle是一個基于Apache Ant和Apache Maven概念的項目自動化構建工具。它使用一種基于Groovy的特定領域語言(DSL)來聲明項目設置,拋棄了基于XML的各種繁瑣配置。Gradle的構建腳本build.gradle和setting.gradle都是可執行的Groovy腳本(不過它們不可以在Groovy運行時環境下運行, 由于上述.gradle文件都需要調用gradle的api運行且后綴不是.groovy). 下面通過與Java對比, 簡單介紹小于Gradle相關的Groovy語言知識.
Groovy是一個基于Java虛擬機的動態語言。這門動態語言擁有類似Python、Ruby和Smalltalk中的一些特性,可以作為Java平臺的腳本語言使用。Groovy的語法與Java非常相似,以至于多數的Java代碼也是正確的Groovy代碼.
Java開發者提供了 現代最流行的編程語言特性,而且學習成本很低。
支持DSL(Domain Specific Languages領域定義語言)和其它簡潔的語法,讓你的代碼變得易于閱讀和維護.
無縫集成所有已經存在的 Java對象和類庫.
接編譯成Java字節碼,這樣可以在任何使用Java的地方 使用Groovy。
下面先給出Groovy運行環境下含義相同的Java和Groovy
代碼片, 然后在說明二者的區別
java
public class Me { private String name; public Me(String name) { this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
groovy
class Me { String name public Me(String name) { this.name = name} }
從上面我們可以看到Groovy版本更加簡潔,下面給出Groovy相對于Java的特點:
表達式后面的分號;
是可選的;
每個類
, 構造器
, 方法
訪問屬性默認是public的
方法體中的最后一個表達式的值被作為返回值, 這意味著return
語句是可選的;
Groovy編譯器自動加上getter/setter方法, 不需要自己手動添加;
類的屬性可以通過點號.
獲取與賦值, 底層是通過調用自動生成的getter/setter方法.
Groovy中用==
比較兩個實例, 底層調用的是equals()方法, 這個操作也可以避免可能的空指針異常.
作為動態語言,groovy中所有的變量都是對象
,在聲明一個變量時,groovy不要求強制類型聲明,僅僅要求變量名前使用關鍵字def
, def關鍵字作為java.lang.Object的一個占位符, 在運行時確定類型.
//assert用于斷言檢查 )def var = 1assert var.class == java.lang.Integer var = "bupt"assert var.class == java.lang.String
在Groovy中如果方法簽名需要至少一個參數, 則方法調用可以省略括號.
def callMe(name) { new Me(name) } callMe('faith') callMe 'faith'println("we could not live without faith!") println "we could not live without faith!"
在Groovy中, 有三種不同方式定義字符串. 帶單引號'
的通常創建等效于Java的String類型; 第二種和Java相同用雙引號"
包起來, 跨行的字符串用三個雙引號包起來"""
.
幾點說明:
跟java一樣,可以使用+
號連接字符串;
Groovy中帶雙引號的字符串可以插值帶變量或者表達式中, 通過$
和花括號{}
表示, 運行時, Groovy計算表達式并組成字符串.這種字符串在Groovy中叫做GString. 通過下面的例子s4
s5
也能看到和單引號的不同.
def s1 = 'bupt'def s2 = "bupt"def s3 = """b u p t """def s4 = "hello "+"${s1}"def s5 = "hello "+'${s1}'println s1 println s2 println s3 println s4
輸出:
buptbupt b u p t hello bupt hello ${s1}
Groovy 中提供了一個減少輸入的特性叫做命名參數(Named Parameter)。GroovyBean 可以通過在構造器調用中傳遞冒號隔開的屬性名稱和值進行構建。如:
class Me { String name } Me me = new Me(name: "faith") println me.name me.name = 'bupt'println me.name
輸出:
faith
bupt
從外部表現上好像是先調用了空構造方法,然后是相應的 setter 方法進行設值。因此,我們所直接想像的應該相當于下列 Java 代碼:
Me me = new Me(); me.setName("faith");
在介紹閉包前,先來講幾個Groovy中代碼塊的一些特性。
groovy的變量作用域和java相似,代碼塊內部聲明的變量不能被外部訪問調用。
對于Groovy Script, 用def定義的變量對binding.variables不可見。沒有def等任何定義的可被binding.variable.參數名所訪問。
對于第一條規則,有個例外,當變量沒有def等任何定義時,該變量全局有效.
代碼塊可以嵌套,比如try代碼塊,這和Java是一樣的。
try{ h = 9 assert binding.variables.h == 9}assert h == 9assert binding.variables.h == 9
閉包是類型為groovy.lang.Closure用花括號{}
括起來的代碼塊. 類似于Python的lambda表達式, 閉包可以被賦值給變量, 作為參數傳遞給方法, 并且像普通方法一樣調用.
看起來,閉包類似于方法,需要定義參數和要執行的語句,它也可以通過名稱被調用。然而閉包對象可以作為參數傳遞. 其次,閉包也可以不命名(當然作為代價,只能在定義閉包時執行一次)
1.顯示參數閉包:
閉包的參數聲明寫在‘->’符號前,調用閉包的的標準寫法是:閉包名.call(閉包參數)。
def toTriple = {n -> n * 3}assert toTriple.call( 5 ) == 15
2.隱士參數閉包:
對于單一存在的參數it可以不用聲明,直接使用it,it在Groovy中有著特殊的意義;當且僅當閉包中有且僅有一個參數,且不顯示聲明,it具有唯一參數引用的作用;如果閉包c是無參數閉包,那么它的標準調用方法是c.call(),它的簡潔調用方法是c()。
c = { it*3 }assert c( 'run' ) == 'runrunrun' def a = 'coffee'def c = { def b = 'tea' a + ' and ' + b }assert c() == 'coffee and tea'
3.閉包隱含參數
參數 | 說明 |
---|---|
it | 默認的參數名,調用是如果沒有傳參數,it為null |
this | 跟Java一樣,是定義閉包所在類的一個引用,不管有多少層閉包嵌套,this指向的都是最上層的類。 |
owner | 封閉閉包的對象(如果只有一層閉包就是this,如果有多層閉包嵌套就是含有此閉包的上層閉包) |
delegate | 缺省值是owner,但是可以改變,后面詳說。 |
4.閉包中的參數名不能重復,it除外。
def name= 'cup'def c={ name-> println (name) } //a compile error when uncommented://current scope already contains name 'name'c= { def d= { 2 * it }; 3 * d(it) }assert c(5) == 30
5.閉包是可嵌套的
def gcd //predefine closure namegcd={ m,n-> m%n==0? n: gcd(n,m%n) }assert gcd( 28, 35 ) == 7
閉包總是會有一個返回值,返回值是閉包的最后一行語句,不論該語句是否冠名return關鍵字。如果閉包最后一句沒有值, 返回 null;
賦值: 閉包賦值給一個變量,和變量與變量間的賦值一致。
def ctry{ def a = 'sugar' c = { a } //a closure always returns its only value}assert c() == 'sugar'def d = c //we can also assign the closure to another variableassert d() == 'sugar'
調用: 調用閉包的方法等于創建一個閉包實例。對于相同閉包創建出來的不同實例,他們的對象是不同的。
c = { def e = { 'milk' }; e } d = cassert c == d v1 = c() v2 = c()assert v1 != v2
delegate委托的用法
delegate委托在是一種常用設計模式,但在java中實現相對比較繁瑣,groovy直接在GroovyObject中已經實現了delegate模式,所以在groovy中應用delegate很方便。
下面看一個狗爸爸讓老貓幫忙照看他的狗兒子玩游戲的例子:
class Dog{ def play = { "wang wang!" } def childmind = { println delegate.play(); } }class Cat { def play = {"mi mi !"} }def dog = new Dog()def cat = new Cat() dog.childmind() dog.childmind.delegate = cat; dog.childmind()
Groovy支持最常見的兩個java集合:
java.util.Collection和java.util.Map。
//1、定義一個集合def collect = ["a","b","c"]//2、給集合增加元素collect.add(1); collect << "come on"; collect[collect.size()] = 100.0//3、集合索引println collect[collect.size()-1] println collect println collect.size()//4、負索引println collect[-1] //索引其倒數第1個元素println collect[-2] //索引其倒數第2個元素//5、集合運算:collect=collect+5 //在集合中添加元素5println collect[collect.size()-1] collect=collect-'a' //在集合中減去元素a(第1個)println collect[0] //現在第1個元素變成b了//6、往集合中添加另一個集合或刪除一個集合:collect=collect-collect[0..4] //把集合中的前5個元素去掉println collect[0] //現在集合中僅有一個元素,即原來的最后一個元素println collect[-1] //也可以用負索引,證明最后一個元素就是第一個元素
Map是“鍵-值”對的集合,在groovy中,鍵不一定是String,可以是任何對象(實際上Groovy中的Map就是java.util.LinkedHashMap)。
//1、定義一個Map:def map = ['name':'john','age':14,'sex':'boy'] println map//2、添加項:map = map+['weight':25] //添加john的體重map.put('length',1.27) //添加john的身高map.father='Keller' //添加john的父親println map//3、兩種方式檢索值:println map['father'] //通過key作為下標索引println map.length //通過key作為成員名索引
閉包中最常見的應用是對集合進行迭代,下面定義了3個閉包對map進行了迭代:
def map = ['name':'john','age':14,'sex':'boy'] map.each( {key,value-> // key,value兩個參數用于接受每個元素的鍵/值 println "$key:$value"}) map.each{println it} //it是一個關鍵字,代表map集合的每個元素map.each({ println it.getKey()+"-->"+it.getValue()})
打印如下:
name:john age:14 sex:boy name=john age=14 sex=boy name-->john age-->14 sex-->boy
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。