Gradle学习(一):你应该知道的Groovy

Groovy是基于JVM的虚拟机的一门语言,语法和Java很类似,而且彻底兼容Java。Java上能写的代码在Groovy中是能够运行的。但同时Groovy引入了闭包,增长了许多特性使用起来较为灵活方便。Gradle脚本使用的是Groovy语法,具有Groovy基础对于学习和使用Gradle是十分重要的。本篇将简要写一些经常使用的Groovy语法相关知识,便于看懂Gradle脚本的一些经常使用写法java

字符串

Groovy中的字符串有三种写法: 单引号写法:markdown

def singleStr = 'single'
复制代码

双引号写法:闭包

def doubleStr = "double"
复制代码

三引号写法:学习

def threeStr = '''Three'''
复制代码

三者的区别:this

单引号写法和Java的字符串相同,singleStr.class == java.lang.String 双引号写法正常状况下和Java字符串相同,但支持插值,当插值时,类型就不等同于Java.lang.String,而是groovy.lang.GString; 即当 def doubleStr = "double"时,类型是java.lang.String 当def doubleStrs = "double ${var}"时,类型是groovy.lang.GString 三引号写法也是java.lang.String,不支持插值。但三引号内支持回车换行的写法,而不须要使用\r\nspa

集合

Groovy的集合code

List

Groovy中,对List的使用作了一些简化orm

task printList << {
	def list = [1,3,5]
	println list.getClass().name
	println list[1]//访问第二个元素
	pringln list[-1]//访问最后一个元素
}
复制代码

打出来的结果是ArrayList,task的使用后续再讲述对象

Map

task printlnMap << {
	def map = ['width':30, 'height':40]
	println map.width
	println map['height']
}
复制代码

方法

实参括号是能够省略的

def addMethod(int a, int b){
	println a+b
}
task invokeMethod << {
	addMethod(3,5)
	addMethod 3, 5
}
复制代码

对比Android中常写的如compileSdkVersion 28,其实是调用方法compileSdkVersion(28)接口

return是能够省略的

def compileMethod(int a, int b) {
	if (a > b) {
		a
	} else {
		b
	}
}
task invokeCompile << {
	def a = compileMethod(3, 5)
	println "${a}"
}
复制代码

当没写返回值时,最后一句语句的值便是返回值

闭包

闭包其实是一段代码段,闭包不是Groovy初创,可是Groovy支持使用闭包

基本用法

def printClosure(closure){
	for (int i = 0; i < 10; i++) {
		closure(i)
	}
}
task closureMethod << {	
	printClosure {
		println it
	}
}
复制代码

上述代码运行closureMethod时,实际上运行的方法为printlnClosure(闭包)上述写法是省略了参数的括号,it是传入闭包的参数

传递参数

def printlnParams(closure){	
	int x = 5
	int y = 6
	closure(x,y)
}
task closureParamsMethod << {
	printlnParams {
		k,v->
		println "x=${k},y=${v}"
	}
}
复制代码

闭包委托

groovy的闭包有三个属性thisObject,owner,delegate. this,owner是肯定的不可修改,而delegate是可修改的,能够灵活使用 this和owner一般状况下是一致的,this指的是离闭包最近的对象(不包含闭包),owner表明闭包定义处最近的对象能够是闭包,delegate默认与owner一致但能够修改。 所以this和owner在闭包中定义闭包的状况下会不一样,其余状况下是一致的,而delegate由于可修改,就取决于修改成什么了

class Person {
	private String name
	int personAge
	def dumpPerson() {
		println "name is ${name}, age is ${personAge}"
	}
}
def person(Closure<Person> closure){
	Person p = new Person()
	closure.delegate = p
	//委托模式优先
	closure.setResolveStrategy(Closure.DELEGATE_FIRST);
	closure(p)
}
//使用
task configClosure << {
	person {
		name="Breeze"
		personAge=20
		dumpPerson()
	}
}
复制代码

闭包在各类配置中用的很是多,尤为是闭包委托的灵活应用

面向对象

定义类

/**
*Groovy中默认都是public,而且默认实现的是GroovyObject接口
**/
class Person {
	String name
	Integer age
	//def返回类型实际上就等同于Object
	def increaseAge(Integer years) {
		this.age += years
	}
}
复制代码

使用类

def person = new Person(name :'Breeze', age:25)
//实际上调用的是get方法,这点与java不一样,不管是点仍是get/set实际上调用的都是get/set
println person.name
复制代码

接口

//只能定义public的方法
interface IAction {
	void doSomething()
}
复制代码

trait类型,相似于java中的抽象类

trait DefaultAction {
	abstract void eat()
	void play() {
		println 'I can play'
	}
}
复制代码

方法:Groovy中的方法和Java中区别比较大,当调用一个方法,Java类中不存在时,编译时就会报错,但Groovy不会,Groovy有一套调用方法的流程,只有当整个流程都不能运行该方法才会报错 流程:类中是否有此方法->metaClass中是否有此方法->是否重写了methodMissing()方法->是否重写了invokeMethod()方法 案例一:

def person = new Person(name:'Breeze', age:25)
//报错,missingMethod,由于上述流程都不能执行方法
person.cry()
复制代码

案例二,改造Person类(invokeMethod):

class Person {
	String name
	Integer age
	//def返回类型实际上就等同于Object
	def increaseAge(Integer years) {
		this.age += years
	}
	def invokeMethod(String name, Object args){
		return "the method is ${name}, the params is ${args}"
	}
}
//使用
def person = new Person(name:'Breeze', age:25)
//不报错,而且打印出the method is cry, the params is []
println person.cry()
复制代码

案例三 改造Person (methodMissing方法重写)

class Person {
	String name
	Integer age
	//def返回类型实际上就等同于Object
	def increaseAge(Integer years) {
		this.age += years
	}
	def invokeMethod(String name, Object args){
		return "the method is ${name}, the params is ${args}"
	}
	def methodMissing(String name, Object args){
		return "the method ${name} is missing"
	}
}
//使用
def person = new Person(name:'Breeze', age:25)
//不报错,而且打印出the method is missing
println person.cry()
复制代码

案例四 改造Person(metaClass使用)

class Person {
	String name
	Integer age
	//def返回类型实际上就等同于Object
	def increaseAge(Integer years) {
		this.age += years
	}
	def invokeMethod(String name, Object args){
		return "the method is ${name}, the params is ${args}"
	}
	def methodMissing(String name, Object args){
		return "the method ${name} is missing"
	}
}
//使用
//使用metaClass增长属性
Person.metaClass.sex = 'male'
//使用metaClass增长方法
Person.metaClass.nameUpperCase = {
	-> name.toUpperCase()
}
//为类增长静态方法
Person.metaClass.static.createPerson = {
	String name, int age -> new Person(name:name, age: age)
}
def person = new Person(name:'Breeze', age:25)
//正确打印出sex属性值
println person.sex
person.nameUpperCase()
pringln person.name
def person3 = Person.createPerson('Breeze', 20)
复制代码

但这种写法只能在当前脚本用,不能在整个项目中用 若是要在整个项目中使用,须要在调用metaClass前执行

ExpandoMetaClass.enableGlobally()
复制代码
相关文章
相关标签/搜索