一、从Java到Groovy的关系
Groovy能直接接受你的Java代码,也就是说在Groovy中写java代码也是可以的,因为Groovy 是一门JVM 语言,也就是,Groovy 的代码最终也会被编译成JVM 字节码,交给虚拟机去执行,我们也可以直接反编译这些字节码文件。从一段你很熟悉的代码开始,在循环中打印三遍hello java。
public void printHello() {
for (int i = 0; i < 3; i++) {
System.out.println("hello java");
}
}
那么改成Groovy语言改如何写呢?其实有多种写法。
a、第一种
for ( i in 0..2 ) {
println("hello Groovy")
}
b、第二种
3.times {
println("hello Groovy")
}
c、第三种
0.upto(2) {
println("hello Groovy")
}
d、第四种
List list = ["hello Groovy", "hello Groovy", "hello Groovy"]
list.each {element->
println(element)
}
上面四种方法的输出结果都是 hello Groovy ,groovy 的方法调用是可以没有括号的,而且也不需要分号结尾。可以见到相对java来说,Groovy语言要稍微简洁一点,但是现在看起来可能有点蒙逼了。下面简单地说一下 groovy 一些语法。
二、Groovy语法
1、变量
有两类可以在生成脚本中声明的变量: 局部变量和额外属性。 在groovy 中,没有固定的类型,局部变量是用def关键字声明的。它们只在定义它们的范围内可以被访问,比如:
def name = 'Jerry'
变量定义时,也可以直接指定类型,比如
def int x = 1
我们通过单引号引用一串字符串的时候这个字符串只是单纯的字符串,内容严格对应Java中的String,不对 符号进行转义,但是如果使用双引号引用,在字符串里面还支持∗∗插值∗∗操作,如果字符中有 号的话,则它会对$表达式先求值。
def name1 = 'Jerry'
def name2="Lisa ,$name1" //name2实际就是Lisa,Jerry
上面属于局部变量,再看看额外属性,Gradle 的域模型中,所有增强的对象都可以容纳用户定义的额外的属性。这包括但并不限于项目(project)、任务(task)和源码集(source set)。额外的属性可以通过所属对象的ext属性进行添加,读取和设置。或者,可以使用ext块同时添加多个属性。比如:
task myTask{
ext.myProperty="value"
}
这表示为myTask创建了一个名字为myProperty属性,值是value
2、方法
类似 python 一样,通过def关键字定义一个方法。无类型的函数定义,必须使用def关键字,方法如果不指定返回值,默认返回最后一行代码的值。
def getNum(def num) {
num * num
}
//如果指定了函数返回类型,则可不必加def关键字来定义函数
int getNum(def num){
num * num
}
getNum(2)的返回值就是4, 函数定义时,参数的类型也可以不指定。比如
def getNum(num) {
num * num
}
上面每一行代码都不需要加上分号,除了每行代码不用加分号外,Groovy中函数调用的时候还可以不加括号。比如:
println("test") ---> println "test"
虽然对于函数调用可以不带括号,但是Groovy经常把属性和函数调用混淆。所以我觉得加上更好。
3、类
class People{
List hobby=['swim','play','watch TV']
String name="Jerry"
int getAge(){
return 20
}
}
在Groovy 中,默认所有的类和方法都是pulic的,所有类的字段都是private的;和java一样,我们通过new关键字得到类的实例,使用def接受对象的引用:def people = new People(),而且在类中声明的字段都默认会生成对应的setter,getter方法。所以我们可以people.getName()来取值,也可以使用people.name来取值,同时我们可以使用people.setName ‘Lisa ,注意,groovy 的方法调用是可以没有括号的,而且也不需要分号结尾。除此之外,我们也可以直接调用;
4、数据类型
Groovy的数据类型主要有三大类,一个是Java中的基本数据类型,一个是Groovy中的容器类,还有一个非常重要的是闭包。
a、基本数据类型
Groovy世界中的所有事物都是对象。所以int,boolean这些Java中的基本数据类型,在Groovy代码中其实对应的是它们的包装数据类型。比如int对应为Integer,boolean对应为Boolean。
b、Groovy中的容器类
- List:链表,其底层对应Java中的List接口,一般用ArrayList作为真正的实现类。
- Map:键-值表,其底层对应Java中的LinkedHashMap。
- Range:范围,它其实是List的一种拓展。
在 Groovy 中,定义一个列表是这样的:
List list = [1, 2, 3, 4, 5]
list[2]=100
println list.size
assert list[2] == 7 //获取下标为2的值
assert list instanceof java.util.List //类型为java.util.List
def list2 = new ArrayList<String>(list1) //创建新集合
def list3 = ['a', 1, 'a', 'a', 2.5, 2.5f, 2.5d, 'hello', 7g, null, 9 as byte] //可以不同类型,并且可以重复,可以为null
如何定义一个Map呢?
def mymap = ['key1':'value1','key2':true]
map的取值是这样
mymap.key1 或者mymap[key1]
Range是Groovy对List的一种拓展,变量定义和大体的使用方法如下:
def range = 1..5
实际上包括 1,2,3,4,5这五个值,这在上面的循环中已经用到过。又比如:
def range = 5..8; //创建左右包含的Rangerange = 5..<8; //不包含8,小于8
c、闭包(Closure)
闭包(Closure)是一种强大的数据类型,对闭包比较书面的一种解释“闭包是可以用作函数参数和方法参数的代码块”。其实Groovy的闭包更象是一个“代码块”或者方法指针,代码在某处被定义然后在其后的调用处执行。简单点说就是代表了一段可执行的代码。其外形如下:
def xxx = {paramters -> code} //或者
def xxx = {无参数,纯code} 这种情况不需要->符号
比如这就是很简单的闭包:
def myClosure={
println("Hello")
}
调用方式:myClosure()
接受参数的闭包:
def myClosure={String str->
println(str)
}
调用方式:myClosure("Hello")
接受多个参数的闭包:
def myClosure={String str,int num->
println("$str ,$num ")
}
调用方式:myClosure("Hello",20)
闭包里面的参数类型可以省略不写:
def myClosure={ str, num->
println("$str ,$num ")
}
调用方式:myClosure("Hello",20)
如果闭包没定义参数的话,则隐含有一个参数,这个参数名字叫it,和this的作用类似。it代表闭包的参数:
def list = [1,2,3,4,5] //定义一个List
list.each{ //调用它的each函数
println it
}
闭包在Groovy中大量使用,比如很多类都定义了一些函数,这些函数最后一个参数都是一个闭包,闭包有点回调函数的感觉。
最后:GroovyAPI:http://www.groovy-lang.org/api.html