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) { // 一些糟糕的事情 }