我是靠谱客的博主 魁梧苗条,最近开发中收集的这篇文章主要介绍Gradle学习(一):Groovy基础,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

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

字符串

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

def singleStr = 'single'

双引号写法:

def doubleStr = "double"

三引号写法:

def threeStr = '''Three'''

三者的区别:

单引号写法和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,不支持插值。但三引号内支持回车换行的写法,而不需要使用rn

集合

Groovy的集合

List

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

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()

最后

以上就是魁梧苗条为你收集整理的Gradle学习(一):Groovy基础的全部内容,希望文章能够帮你解决Gradle学习(一):Groovy基础所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(35)

评论列表共有 0 条评论

立即
投稿
返回
顶部