public static void main(String[] args) { // 重要的事情說3遍 for (int i = 0; i < 3; i++) { System.out.println("Java的東西Groovy都能用"); } // 再3遍 for (i in 0..2) { println 'Java的東西Groovy都能用' } // 又3遍 3.times { println 'Java的東西Groovy都能用' } }
java.lang java.util java.io java.net java.math.BigDecimal java.math.BigInteger groovy.lang groovy.util
寫了也沒事java
// 單行註釋 println "hello groovy," /* 多行註釋 */ + "I'm Atlas."
as、assert break case、catch、class、const、continue def、default、do else、enum、extends false、finally、for goto if、implements、import、in、instanceof、interface new、null package return super、switch this、throw、throws、trait、true、try while
能夠這樣:數組
void doSomething(def param1, def param2) { }
也能夠這樣:閉包
void doSomething(param1, param2) { }
Groovy的類和方法的默認修飾符都是public,且能夠省略不寫。因爲修飾符能夠省略、方法返回類型能夠省略、方法參數類型能夠省略。因此Java的類和main方法的結構能夠簡化爲:ide
class HelloGroovy { static main(args) { } }
String toString() { return "a server" } //可寫成: String toString() { "a server" }
對於頂級表達式,Groovy 容許省去括號,好比 println 命令:ui
println "Hello"
'a' to 'z' (lowercase ascii letter) 'A' to 'Z' (uppercase ascii letter) '\u00C0' to '\u00D6' '\u00D8' to '\u00F6' '\u00F8' to '\u00FF' '\u0100' to '\uFFFE'
def map = [:] map."an identifier with a space and double quotes" = "ALLOWED" map.'with-dash-signs-and-single-quotes' = "ALLOWED" assert map."an identifier with a space and double quotes" == "ALLOWED" assert map.'with-dash-signs-and-single-quotes' == "ALLOWED" map.'single quote' map."double quote" map.'''triple single quote''' map."""triple double quote""" map./slashy string/ map.$/dollar slashy string/$
char c1 = 'A' // 類型聲明爲char assert c1 instanceof Character def c2 = 'B' as char // 經過as將類型強制指定爲char assert c2 instanceof Character def c3 = (char)'C' // 經過類型轉換
// 單引號 println('a single quoted string') assert 'ab' == 'a' + 'b' 執行結果爲: a single quoted string
println('''這是一段文本。 換行啦!!! 前面有四個空。。。 又換行啦!!!''') 執行結果爲: 這是一段文本。 換行啦!!! 前面有四個空。。。 又換行啦!!!
// 雙引號 def name = 'Atlas' def greeting = "Hello ${name}" println greeting assert greeting.toString() == 'Hello Atlas' def sum = "The sum of 2 and 3 equals ${2 + 3}" println sum assert sum.toString() == 'The sum of 2 and 3 equals 5' def person = [name: 'Guillaume', age: 36] println "$person.name is $person.age years old" assert "$person.name is $person.age years old" == 'Guillaume is 36 years old' 執行結果爲: Hello Atlas The sum of 2 and 3 equals 5 Guillaume is 36 years old
def name = 'Groovy' def template = """ Dear Mr ${name}, You're the winner of the lottery! Yours sincerly, Dave """ println template assert template.toString().contains('Groovy') 執行結果爲: Dear Mr Groovy, You're the winner of the lottery! Yours sincerly, Dave
Groovy的整型和Java相似:this
byte char short int long java.lang.BigInteger e.g. // primitive types byte b = 1 char c = 2 short s = 3 int i = 4 long l = 5 // infinite precision BigInteger bi = 6
若是使用def聲明類型,那麼這個整型是可變的。它會數值的大小來匹配類型。(負數也如此)spa
def a = 1 assert a instanceof Integer // Integer.MAX_VALUE def b = 2147483647 assert b instanceof Integer // Integer.MAX_VALUE + 1 def c = 2147483648 assert c instanceof Long // Long.MAX_VALUE def d = 9223372036854775807 assert d instanceof Long // Long.MAX_VALUE + 1 def e = 9223372036854775808 assert e instanceof BigInteger def na = -1 assert na instanceof Integer // Integer.MIN_VALUE def nb = -2147483648 assert nb instanceof Integer // Integer.MIN_VALUE - 1 def nc = -2147483649 assert nc instanceof Long // Long.MIN_VALUE def nd = -9223372036854775808 assert nd instanceof Long // Long.MIN_VALUE - 1 def ne = -9223372036854775809 assert ne instanceof BigInteger
浮點數類型和Java相似:.net
float double java.lang.BigDecimal e.g. // primitive types float f = 1.234 double d = 2.345 // infinite precision BigDecimal bd = 3.456
浮點數類型支持指數,經過e或E實現。code
assert 1e3 == 1_000.0 assert 2E4 == 20_000.0 assert 3e+1 == 30.0 assert 4E-2 == 0.04 assert 5e-1 == 0.5
爲了計算的準確性,Groovy使用BigDecimal做爲浮點數的默認類型。除非顯示的聲明float或double,不然浮點數類型爲java.lang.BigDecimal。儘管如此,在一些接受參數爲float或double的方法中,依然可使用BigDecimal類型做爲參數傳遞。server
當數值過長的時候,可使用_對數字進行分組,以使閱讀更加簡潔明瞭。
long creditCardNumber = 1234_5678_9012_3456L long socialSecurityNumbers = 999_99_9999L double monetaryAmount = 12_345_132.12 long hexBytes = 0xFF_EC_DE_5E long hexWords = 0xFFEC_DE5E long maxLong = 0x7fff_ffff_ffff_ffffL long alsoMaxLong = 9_223_372_036_854_775_807L long bytes = 0b11010010_01101001_10010100_10010010
數值類型後綴
BigInteger類型後綴爲G或g Long類型後綴爲L或l Integer類型後綴爲I或i Bigdecimal類型後綴爲G或g Double類型後綴爲D或d Float類型後綴爲F或f
布爾類型是一種特殊的類型用於判斷對或錯:true或false。Groovy有一套特別的規則用於強制將non-boolean類型轉換爲bollean類型。
Groovy中沒有定義本身的List類型,使用的是java.util.List類型。經過一對[]包括,裏面的元素以,分隔來定義一個List。默認狀況下,建立的List的類型爲java.util.ArrayList。
def numbers = [1, 2, 3] assert numbers instanceof List assert numbers.size() == 3
List中元素能夠是不一樣類型:
def heterogeneous = [1, "a", true]
經過使用as操做符能夠強制指定List的類型,或者在聲明List變量時強制指定類型。
def arrayList = [1, 2, 3] assert arrayList instanceof java.util.ArrayList def linkedList = [2, 3, 4] as LinkedList assert linkedList instanceof java.util.LinkedList LinkedList otherLinked = [3, 4, 5]
可使用[]獲取List中的元素,可使用<<向list末尾追加元素。
def letters = ['a', 'b', 'c', 'd'] assert letters[0] == 'a' assert letters[1] == 'b' assert letters[-1] == 'd' assert letters[-2] == 'c' letters[2] = 'C' assert letters[2] == 'C' letters << 'e' assert letters[ 4] == 'e' assert letters[-1] == 'e' assert letters[1, 3] == ['b', 'd'] assert letters[2..4] == ['C', 'd', 'e']
Groovy定義數組的方式和定義list的方式同樣,只不過聲明時須要制定類型,或者經過as來強制制定類型爲Array。
String[] arrStr = ['Ananas', 'Banana', 'Kiwi'] assert arrStr instanceof String[] assert !(arrStr instanceof List) def numArr = [1, 2, 3] as int[] assert numArr instanceof int[] assert numArr.size() == 3 //多維數組 def matrix3 = new Integer[3][3] assert matrix3.size() == 3 Integer[][] matrix2 matrix2 = [[1, 2], [3, 4]] assert matrix2 instanceof Integer[][]
Groovy不支持Java數組的初始化方式。
Map定義方式爲:使用[]包括,裏面的元素爲key/value的形式,key和value以:分隔,每一對key/value以逗號分隔。Groovy穿件的map默認類型爲java.util.LinkedHashMap。
def colors = [red: '#FF0000', green: '#00FF00', blue: '#0000FF'] assert colors['red'] == '#FF0000' assert colors.green == '#00FF00' colors['pink'] = '#FF00FF' colors.yellow = '#FFFF00' assert colors.pink == '#FF00FF' assert colors['yellow'] == '#FFFF00' assert colors instanceof java.util.LinkedHashMap
Map中經過[key]或.key的方式來獲取key對應的value。若是key不存在,則返回null。
assert colors.unknown == null
當咱們使用數字做爲key時,這個數字能夠明確的認爲是數字,並非Groovy根據數字建立了一個字符串。可是若是以一個變量做爲key的話,須要將變量用()包裹起來,不然key爲變量,而不是變量所表明的值。
def key = 'name' def person = [key: 'Guillaume'] // key實際上爲"key" assert !person.containsKey('name') assert person.containsKey('key') person = [(key): 'Guillaume'] // key實際上爲"name" assert person.containsKey('name')
/ 範圍從1到10 def demoRange = 1..10 // 範圍從1到9 def demoRange2 = 1..<10 println(demoRange2.from) // 獲取起始值 println(demoRange2.to) // 獲取最大值
閉包是一段代碼塊,注意閉包也是數據類型,因此能夠把閉包做爲方法的參數或者返回類型。 若是咱們要篩選指定數n範圍內的奇數,普通寫法以下:
def getOdd(n) { for (i in 1..n) { if (i % 2 != 0) println i } } getOdd(10)
若是要獲取偶數,又要再寫一個方法:
def getEven(n) { for (i in 1..n) { if (i % 2 == 0) println i } } getEven(10)
這兩個方法其實for循環部分的內容是重合的。 而若是用閉包就不會這樣了,例以下面的pick接受兩個參數,一個參數n,另一個是閉包(closure是變量名隨便取)。再重複一遍閉包是一個代碼塊,這裏傳進來你想在遍歷過程作什麼。至於怎麼把便利過程的i傳遞給閉包,閉包有一個隱式變量叫it,能夠接收一個參數。
看代碼:
def pick(n, closure) { for (i in 1..n) { closure(i) } } // 打印奇數 pick(10, { if (it % 2 != 0) // it表明傳進來的參數,也就是上面closure(i)的i println it }) // 打印偶數 pick(10, { if (it % 2 == 0) println it })
總之循環結構不須要本身寫了,你只須要寫你想在遍歷過程當中作什麼,例如若是要打印所有數的平方能夠這樣:
// 平方 pick(10, { println it **= 2 })
若是有一些行爲是常常用的,你也給閉包取個名字固定下來啊就像定義變量同樣。例如若是把剛纔的的打印奇數、打印偶數和打印平方定義成變量能夠改爲這樣:
def pick(n, closure) { for (i in 1..n) { closure(i) } } // 打印奇數 def getOdd = { if (it % 2 != 0) println it } // 打印偶數 def getEven = { if (it % 2 == 0) println it } // 打印平方 def getSquare = { println it **= 2 } pick(10, getOdd) pick(10, getEven) pick(10, getSquare)
隱式變量it只能表明一個參數吧?閉包怎麼接收多個參數?是這樣的,用 -> 把參數列表和行爲隔開便可。假設咱們定義一個閉包接受兩個參數求他們的和:
def getSum = { x, y -> println x + y } getSum(3, 4) // 閉包能夠直接調用
關於閉包還有個說的,就是假設你的閉包不須要接收參數,可是仍是會自動生成隱式it,只不過它的值爲null。也就是說,閉包至少包含一個參數。
沒必要本身建立字段和 getter/setter,只需把這些活兒留給 Groovy 編譯器便可:
class Person { String name }
編譯後:
public class Person implements GroovyObject { private String name; public Person() { CallSite[] var1 = $getCallSiteArray(); MetaClass var2 = this.$getStaticMetaClass(); this.metaClass = var2; } public String getName() { return this.name; } public void setName(String var1) { this.name = var1; } }
Java 的 == 實際至關於 Groovy 的 is() 方法,而 Groovy 的 == 則是一個更巧妙的 equals()。
要想比較對象的引用,不能用 ==,而應該用 a.is(b)。
可使用 assert 語句來檢查參數、返回值以及更多類型的值。與 Java 的 assert 有所不一樣,Groovy 的 assert 並不須要激活,它是一直被檢查的。
若是不關心 try 語句塊中所要拋出的異常類型,能夠只捕捉異常而忽略它們的類型。因此,像下面這樣的語句:
try { // ... } catch (Exception t) { // 一些糟糕的事情 }
就能夠變成下面這樣捕捉任何異常(any 或 all 均可以,只要是能讓你認爲是任何東西的詞兒就能夠用):
try { // ... } catch (any) { // 一些糟糕的事情 }