1.字符串
在Groovy中,单引号和双引号都可以表示一个字符串,不同的是单引号标记的是纯粹的字符串常量,而双引号可以对其中的字符串表达式做运算。
def Task printStr = task(printStr) {
def str1 = '单引号'
def str2 = "双引号"
println "str1=" + str1.getClass().name
println "str2=" + str2.getClass().name
println 'str1=$str1'
println "str2=${str2}"
}
输出结果;
str1=java.lang.String
str2=java.lang.String
str1=$str1
str2=双引号
2.集合
2.1 List
2.1.1 声明: def lis=[“A”,“B”,“C”]
task printList{
def lis=["A","B","C"]
println lis.getClass().name
}
输出结果:
java.util.ArrayList
2.1.2 访问和修改
task printList{
def lis=["A","B","C"]
println lis[0]
println lis[-1]
println lis[0..2]
lis[0]="AAA"
println lis[0]
}
输出结果:
A
C
[A, B, C]
AAA
2.1.3 遍历
task printList{
def lis=["A","B","C"]
lis.each{
println it
}
}
输出结果:
A
B
C
3.1 Map
3.1.1 声明
task printMap{
def map=["name":"kylip","age":20]
println map.getClass().name
}
输出结果:
java.util.LinkedHashMap
3.1.2 访问和修改
task printMap{
def map=["name":"kylip","age":20]
//访问
println "name=${map.name},age=${map.age}"
println "name=${map["name"]},age=${map["age"]}"
//修改
map.name="alice"
map.age=18
//访问
println "name=${map.name},age=${map.age}"
println "name=${map["name"]},age=${map["age"]}"
}
输出结果:
name=kylip,age=20
name=kylip,age=20
name=alice,age=18
name=alice,age=18
3.1.3 遍历
task printMap{
def map=["name":"kylip","age":20]
map.each{
println "${it.key},${it.value}"
}
map.findAll{
println "${it.key},${it.value}"
}
map.find{
println "${it.key},${it.value}"
}
}
输出结果:
name,kylip
age,20
name,kylip
age,20
name,kylip
age,20
3.方法
3.1 括号是可以省略的
def Task testFunction = tasks.create("testFunction") {
method1("kylip", 20) //带括号
method1 "kylip", 20 //不带括号
}
def method1(String name, int age) {
println "$name, $age"
}
输出结果:
kylip, 20
kylip, 20
3.2 return是可以不写的
在Groovy中return是可以不写的,默认把最后一行代码作为返回值。
def Task testFunction = tasks.create("testFunction") {
def maxIntValue = getMaxIntValue 20, 18
println maxIntValue
}
def getMaxIntValue(int a, int b) {
if (a > b) {
a
} else {
b
}
}
输出结果:
20
3.3 代码块是可以作为参数传递的
task demo {
def lis = ["A", "B", "C"]
//原始写法
lis.each({ println(it) })
//格式化
lis.each(
{ println(it) }
)
//在Groovy中,如果最后一个参数是闭包可以放到括号外面
lis.each() {
println(it)
}
//见3.2,方法的括号是可以省略的
lis.each {
println(it)
}
}
输出结果:
A
B
C
A
B
C
A
B
C
A
B
C
4.JavaBean
在Groovy中,我们不用生成getter/setter方法,可以直接快速的访问和修改JavaBean的属性。
task javaBean {
Person person = new Person()
person.name = "kylip"
println person.name
}
class Person {
String name
}
输出结果:
kylip
在Groovy中,并不是一定要定义为成员变量才能作为类的属性访问,使用getter/sette方法也可以当作属性进行访问。
task javaBean {
Person person = new Person()
println person.name
}
class Person {
def getName(){
"kylip"
}
}
输出结果:
kylip
通过上面的例子我们可以知道,我们可以通过定义getter/setter方法,然后像类的属性一样访问它们。但是需要注意的是,如果只定义getter没有定义setter则不能修改name的值,同理只定义setter而没有定义getter则不能获取name的值。
只定义getter:
task javaBean {
Person person = new Person()
person.name="alice"
println person.name
}
class Person {
def getName(){
"kylip"
}
}
输出结果:
只定义setter:
task javaBean {
Person person = new Person()
person.name = "alice"
println person.name
}
class Person {
def setName() {
}
}
输出结果:
5.闭包
5.1 什么是闭包?
闭包其实就是一段代码块;也可以理解为是定义在函数中的内部函数,内部定义的函数可以访问外部函数的参数和变量。
在Groovy中可以理解为一段代码块,可以定义在类和闭包中。
每个闭包都可以理解为是一个groovy.lang.Closure对象。
5.2 闭包的定义
格式:{ closureParameters ->statement }
其中closureParameters代表参数,多参数用逗号分割,用->隔开参数与内容,没有参数可以不写->,默认参数为it。
//简单的代码块,打印"Hello World"
def closure1 = { println "Hello World" }
//不声明默认参数it并打印
def closure2 = { println it }
//声明默认参数it并打印
def closure3 = { it -> println it }
//自定义参数
def closure4 = { customParam -> println customParam }
//多个参数的闭包
def closure5 = { k, v -> println "$k,$v" }
5.3 闭包的调用
闭包两种调用方式:
第一种是闭包名称后面直接添加括号调用。
第二种是使用.call()方法调用。
两种方法都支持参数传递。
task testClosure{
closure1()
closure2.call("closure2")
}
闭包可以作为参数传递
task closure {
def lis = ["A", "B", "C"]
eachList(lis) {
println it
}
}
def eachList(ArrayList<String> list, closure) {
for (int i = 0; i < list.size(); i++) {
closure(list.get(i))
}
}
输出结果:
A
B
C
5.4 向闭包传递参数
task closure {
def map = ["name": "kylp", "age": 20]
eachMap(map) { key, value ->
println "$key,$value"
}
}
def eachMap(Map<String, String> map, closure) {
map.each {
closure(it.key, it.value)
}
}
输出结果:
name,kylp
age,20
5.5 闭包委托
5.5.1 三个重要内置对象
Groovy闭包的强大之处在于它支持闭包方法的委托。在闭包中有三个内置对象,this(thisObject),owner,delegate。在实际应用中既可以使用this(thisObject),owner,delegate来调用,也可以使用getThisObject(),getOwner(),getDelegate()来调用,它们是等同的。
- this(thisObject),owner,delegate三个对象的含义:
- this(object):对应定义闭包的那个类,如果在内部类中,指向的就是内部类。
- owner:对应定义闭包的那个类或闭包,如果定义在闭包中,指向的就是闭包,否则和this一致。
- delegate:默认是和owner一致,不同点在于delegate可修改,可自定义指向。
task closure {
OutClass.InnerClass innerClass = new OutClass.InnerClass()
innerClass.outerClosure.call()
}
class OutClass {
class InnerClass {
def outerClosure = {
def innerClosure = {
}
println "------打印定义在内部类中的闭包信息------"
printInfo(outerClosure)
println "------打印定义在闭包中的闭包信息------"
printInfo(innerClosure)
}
void printInfo(closure) {
println "Closure-this:${closure.getThisObject().toString()}"
println "Closure-owner:${closure.getOwner().toString()}"
println "Closure-delegate:${closure.getDelegate().toString()}"
}
}
}
输出结果:
------打印定义在内部类中的闭包信息------
Closure-this:OutClass$InnerClass@145b56f0
Closure-owner:OutClass$InnerClass@145b56f0
Closure-delegate:OutClass$InnerClass@145b56f0
------打印定义在闭包中的闭包信息------
Closure-this:OutClass$InnerClass@145b56f0
Closure-owner:OutClass$InnerClass$_closure1@1b9da64
Closure-delegate:OutClass$InnerClass$_closure1@1b9da64
5.5.2 修改delegate指向
默认情况下在闭包中访问的属性和方法会优先在owner下寻找,owner没有则在delegate下寻找。可以设置委托模式。默认委托模式为:Closure.OWNER_FIRST。
委托模式
Closure.OWNER_FIRST:0 默认策略,优先在owner寻找,找不到则在delegate寻找。
Closure.DELEGATE_FIRST:1 优先在delegate寻找,找不到则在owner寻找。
Closure.OWNER_ONLY:2 只在owner中寻找。
Closure.DELEGATE_ONLY:3 只在delegate中寻找。
设置和获取委托模式
getResolveStrategy()
setResolveStrategy()
task closure {
Person person = new Person()
def testClosure = {
name = "kylp"
age = 20
sayHi()
}
testClosure.delegate=person
testClosure.call()
println person.toString()
}
class Person {
String name
int age
void sayHi() {
println "Hi"
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
输出结果:
Hi
Person{name='kylp', age=20}