概述
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基础所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复