走进Groovy (二)
承接上一篇,配置好环境后,开始正式学习语法。我假设看此文的同学至少会一定的JAVA语法,因此一些太过基础的就不记录了,基本上,大家看看示例就明白了。
Groovy的卖点之一,就是全兼容JAVA的语法,因此你完全可以从一个JAVA文件中把源代码复制到一个Groovy文件中而不必改写任何一个字直接运行,不过这样在groovy中写JAVA就没意思了,享受不到groovy带来的乐趣了。
一个groovy文件,并非像java文件一样,必须要定义一个类且文件名必须和类名一样,groovy文件中,你可以同时定义好几个类,也可以没有类,像这样:
println("hello groovy")
println "hello world"
可以看到groovy对于代码要求比较宽松,可以没有分号,可以没有函数调用时的括号。
当groovy引用JAVA类时,groovy自动会导入java.lang,java.util,java.io,java.net以及BigDecimal、BigInteger两个类,以及一些groovy包。
一. 一些杂项的语法扩展
直接上代码吧
//输出从1到10,后面的是闭包,如果只有一个参数,并且没指定参数名的话,默认名就是it 1.upto(10) { println it } //从10到1 10.downto(1) { println it } //循环10次 10.times { println it } //相当 for(int i=0;i<10;i+=3) 0.step(10,3) { println it } //只有当实例不为null时才调用方法 String str = null println str?.toUpperCase() //groovy对于异常比较宽松,可以不处理异常,异常发生时会抛给调用者 Thread.sleep(10) //不用一定要处理异常
二. 类定义及方法
- 类和方法默认是public
- 可以没有return,最后一项的值就是返回值
- 用def申请属性及方法,可以不带类型
class Book{ //可以指定类型,如果是给JAVA调用的,还是指定类型的好 String name //不指定类型 def price def String toString(){ "$name : $price" } }
看看在JAVA中调用这个类的情况:
可以看到,groovy自动生成的getter和setter方法,只是如果没有指定类型的话,类型默认是Object类型。
三. 参数及返回值
- 具名变量:灵活的初始化
- 可选参数:方法的默认值
- 多赋值:一次赋值多个变量
//具名参数,这要求类有无参构造函数 //相当于建立实例后,初始化各属性 //具名参数比较灵活,特别是传入map的时候,有需求的同学自己查一下 def book = new Book(price:20.5, name:'Groovy Book') println book //默认参数(可选参数) //可选参数必须位于参数最后边 def say(txt,t=5){ t.times { println txt } } //默认显示5次 say 'hello' //显示3次 say 'world', 3 //返回多值 def mult(){ [1,3] //把要返回的多个值放于数组中 } //直接把数组分拆,赋值给a和b //如果返回的值多于变量,则丢弃多余值 //如果返回的值少于变量,则其余变量为null def (a,b) = mult() println a println b
四. 实现接口
grovvy中不要求实现所有接口方法,如果那些方法用不到的话,完全可以不实现。同时,只要参数一致,groovy中的代码块可以转成任意接口。
List<Integer> list = new ArrayList<Integer>() list.add(1) list.add(3) list.add(7) list.add(4) //直接实现 list.sort({a,b-> a <=> b //飞船操作符 :) }) for(x in list) println x //实现有多个方法的接口 interface Action{ void eat(); void drink(); } def action = [ eat: {println "amu amu" }, drink: {println "gudu gudu" } ] //定义调用接口的方法 def callAction(Action act){ act.eat() act.drink() } callAction( action as Action )
五. 布尔转换
在JAVA中,只有true和false两种布尔值,在groovy中,则什么类型都可以转换为布尔值,具体转换如下:
类型 | 为true的条件 |
Boolean | 值为true |
Collection | 集合不为空 |
Character | 值不为0 |
CharSequence | 长度大于0 |
Enumeration | hasMoreElements()为true |
Iterator | hasNext()为true |
Number | 值不为0 |
Map | 不为空 |
Matcher | 至少一个匹配 |
数组 | 长度大于0 |
其他类型 | 引用不为null |
在自己类中,如果实现asBoolean()方法,则可以自己控制如何转化为boolean
//一般来说,如果引用不为null则为true //但是实现了asBoolean方法的话,则按照该方法返回值 class MyBoolean{ def asBoolean(){ false } } def b = new MyBoolean() println b ? "true" : "false" //false