前语

引证 Gradle 官方一段对Gradle的介绍:Gradle is an open-source build automation tool focused on flexibility and perJavaformance. Gradle build scripts are written using a Groovy or Kotlin DSL.翻译实例化类过来便是:Gradle 是一个开源的主动http 302化构建东西,专心于活络性和功用。GrScalaadle 构建脚本是运用 Groovy 或 Kotlin DSL 编写的。 之前官网的介绍是说 Gradle 是依据 Groovy 的 DSL,为啥现在又多了个 Kotlin 呢?由于 Gradl实例化是什么意思e 从5.0初步,初步支撑了 Kotlin DSL,现在现已展开到了6.8.3,因而咱们能够运用 Ghttps和http的差异roovy 或许 Kotlin 来编写 Gradle脚本。Kotlin 现作为 Android 榜首开发言语,重要性显而易见,作为一个 Android开发者,Kotlin 是必学的,后续我也会出个 Kotlin 系列文章。今天咱们的要害是介绍一些 Gradle实例化数组 的相关概念,以及对 Groovy 言语的学习

一、问题

我学习常识喜欢以问题为导向,这样能够让我清晰学习的意图,前进学习功率,下面也是我在学习 Gradle 的进程中数组初始化,由浅入深所产生的一些疑问,咱们都知道,Android 应用是用 Gradle 构建的,在刚开发 Android 的时分我会想:

1、什么是主动化构建东西?

2、G数组radscala装置le 是什么?

3、什么是 DShttp 500L?

4、什么是 Groovy数组去重

5、Gradle 和 Groovy 有什么差异?

6、静态编程言语和动态编程言语有什么差异?

带着这些疑问,咱们继续学习

1、主动化构建东西

在 Android 上的体现,简略的说便是主动化的编译、打包程序

在上大学学习 Java 那会,老师为了让咱们深化的体会撸码的魅力,都实例化需求是经过文本直接敲代码的,敲完之后把扩展名改成.java后缀,然后经过javacscala环境装备指令编译,编译经往后,在实行java指令去工javahdxx作,那么这种文件一多,咱们每次都得手动去操作,功率会大大的下降,这个时分就出现了主动化编译东西,咱们只需求在编译东西中,点击编译按钮,编译结束后,无需其他手动操作,程序就能够直接作业了,主动化https和http的差异编译东西便是最早的主动化构建东西。那么跟着事务功用的不断扩展,咱们的产品需求参与多媒体资源,需求打不同的途径包发布到不同的途径,那就java模仿器有必要依托主动化http://192.168.1.1登录构建东西,要能支撑渠道、需求等方面的差异、能添加自界说使httpclient命、专scalar门的用来打包生成究竟产实例化品的一个程序、东西,这个便是主动化构建东西。主动化构建东西本质上仍是一段代码程序。这便是主动化构建东西的一个展开历程,主动化构建东西在这个进程中不断的展开和java面试题优化

2、Gradle 是什么?

了解了主动化构建东西,那么了解 Gradle 就比较简略了,仍是引证官方的那一段话:

Gradle 是一个开源实例化类的主动化构建东scala是什么西,专心于活络性和功用。Gradle 构建脚本是运用 Groovy 或 Kotlin DSL 编写的scala菜鸟教程

Gradle 是 Android 的默许构建东西,Android 项目这数组去重的5种办法么多东西,既有咱们自己写的 java、kotlin、C++、Djava环境变量装备art 代码http://www.baidu.com,也有系统数组的界说自己的 java、C,C++ 代码,数组函数的使用办法还有引进的第三方代码,还有多媒体资源,这么多代码、资源打包成 APK 文件必定要有一个规数组函数的使用办法范,干这个活的便是咱们了解的scala是什么 gradle 了,总而言之,Gradle便是一个帮咱们打包 APK 的东西

3、什么是DSL?

DSL英文全称:domain specific language,中文翻译即范畴特定言语,例如:HTMhttpclientL,XML等 DSL 言语

特征

  • 处理特定范畴的专有问题
  • 它与系统编程言语走的是两个极点,系统编程言语是期望处理悉数的问题,比方 Java 言http署理语期望httpclient能做 Android 开发,又期望能做后台开发,它具有横向扩展的特性。而 DSL 具scalability有纵向深化处理特定范畴专有问题的特性。

实例化目标是什么意思的来说,DSL 的中心思维便是:“求专不求全,处理特定范畴的问题”。

4、什么是 Groovy?

Groovy 是依据 JVM 的脚本言语,它是依据Java扩展的动态言语

依据 JVM 的言语有许多scalar是什么意思种,如:Groov数组去重y,Kotlin,Java,Scala等等,他们都拥scala教程有一个一起的特性:究竟都会编译生成 Java 字节码文件并在 JVM 上作业。

由于 Groovy 便是对 Java 的扩展,所以,咱们能够用学习 Java 的办法去学习 Groovyhttp协议 。 学习本钱相对来说仍是比较低的,即便开发进程中遗忘 Groovy 语法,也能够用 Java 语法继续编码

5、Gradle 和 Groovy 有什么差异?

G数组词radle 是依据 Groovy 的一种主动化构建东西,是作业在JVM上的一个程序,Groovy是依据JVM的一实例化一个类scala环境装备言语,Gradle 和 Groovy 的联络就像 Android 和 Java 的联络相同

6、静态编程言语和动态编程言语有什么差异?

静态编程言语是在编译期就要scala菜鸟教程供认变量的数据类型,而动态编程言语则是在作业期供认变量的数据类型。就像静态署理和动态署理相同,一个侧scalable重的是编译期,一个侧重的是作业期,常见的静态编程言语有Java,Kotlijava名优馆在线六区n等等,动态编程言语有Groovy,Phttp 302ython等言语java名优馆在线六区

二、数组函数的使用办法Groojavahdxxvy 开数组排序发环境树立与工程http 302创立

1、到官网下载JDK设备,并装备好 Jhttp 404DK 环境

  • JDK下载
  • JDK环境变量树立

2、到官网下载好 Groovy SDK,并解压到适合的方位

  • Groovy SDK 下载链接

3、装http://www.baidu.com备 Groovy 环境变量

  • Groovscala菜鸟教程y 环境变量

4、到官网下载 IntelliJ IDEA 开发东西并设备

  • IntelliJ IDEA 开发东西下载

5、创立 Groovy 工程即可

结束了上述4个进程,咱们初步创立一个 Groovy 工程:

依照上述图片中进程即可结束一个 Groovy 工程创立,下面就能够运用 IntelliJ IDEA 这个东西来学习 Groovy 了,我下面悉数代码都是在 IntelliJ IDEA数组指针 上跑的

小技巧: 作为 Android 开发者,咱们一般都是运用 Androi数组的界说dStudio 进行开发的,但是 AndroidStudio 关于 G实例化roovy 支撑不是很和睦,各种没有提示,涉及到闭包,你也不知道闭包的参数是啥?因而这个时分,你就能够运用 IntelliJ IDEA 先弄好,在拷贝曩昔,IntelliJ IDEA 对Groovy 的支撑仍是很和http 500睦的

三、Groovy 根底语法

再次侧重 Groovy 是依据 java 扩展的动态言语,直接写 java数组c言语 代码是没问题的,既然如此,Groovy 的优势在哪里呢?

在于 Groovy 供给了愈加活络简略的语法,大实例化需求量的语法糖以及闭包特功用够让你用更少的代码来结束和 Java 相同的功用。比方解析xml文件,Groovy 就非常便利,只需求几行代码就能搞定,而假定用实例化目标 Java 则需求几十行代码。

1、支撑动态类型,运用 def 要害字来界说一个数组词变量

在 Groovy 中能够运用 def 要害字界说一个变量,当然 Java 里间隔说数据类型的办法,在 Groovy 中都能用

//数组去重Java 中,咱们一般会这么界说
int age = 1http协议6
String name = "erdai"
//Groovy 中,咱们能够这样界说,在变量数组c言语赋值后,Grjava面试题oovy 编scalable译器会推断出变量的实践类型
def age = 16
def name = 'erdai'

2、不必写 ; 号

现在比较新的言语都不必写,如 Kotlin

def age = 16
def name = 'erdai'

3、没有根柢数据类型数组了,满是引证类型

上面说到,界说一个变量运用 def 要害字,可scalable是 Groovy 是依据 Java 扩展的,因而咱们也能够运用 Java 里边的类型,如 Jscala怎样读ava 中8Scala大根柢类型:byte , short , int , long , float , double ,char,boolean

//界说8大根柢类型
byte mByte = 1
short mShort = 2
int mIn数组公式t = 3
long mLong = 4
float mFloat = 5
double mDouble = 6
char mChar = 'a'
boolean mBoolean = true
//对类型进行打印
println(mByte.class)
println(mShort.class)数组的界说
println(mInt.class)
println(mLong.clasjavahdxxs)http 500
println(mFloat.class)
println(scalarmDouble.class)
println(mChar.class)
println(mBooljava模仿器ean.class)
//打印作用如下:
class java.lang.Byte
class java.lang.Short
class java.lang.Integer
class java.lang.Long
class java.lang.Float
cla实例化类ss java.lang.Double
class java.lahttp://www.baidu.comng.Character
class java.lang.Boolean

因而咱们能够得出定论:Groovy中没有根柢数据类型,满是引证类型,即便定数组去重的5种办法义了根底类型,也会被转化成对应的包装类

4、办法改动

1、运用 def 要害字界说一个办法,办法不需求指定回来值http 500类型,参数类型,办法体内的毕竟一行会主动作为回来值,数组而不需求return要害字

2、办法调用能够不写 () ,最好仍是加上 () 的好,不然可scala环境装备读性欠好

3、界说办法时,假定参数没有回来值类型,咱们能够省掉 def,运用 voscala环境装备id 即可

4、实践上不管有没有回来值,Groovy 中回https和http的差异来的都是 Object 类型

5、类的结构办法,防止添加 def 要害字

def sum(a,b){
a + b
}
def sum = sum(1,2) //还能够写成这样,但是可读性欠好 def sumscala怎样读 = sum 1,2 
println(sum)
//打印作用
3
//假定办法没有回来值,咱们能够这样写:
void dojava名优馆在线六区Something(param1, param2) {
}
//类的结构办法,防止添加 def 要害字
class MyClass {
MyCl实例化是什么意思ass() {
}
}

5、字符串改动

在 Groovy 中有三种常用的字符串界说办法,如下所示:

这儿先解释一下可扩展字符串的意义,可扩展字符串便是字符串里边能够引证变量,表达式http://192.168.1.1登录等等

1 、单引号 ” 界说的字符串为不行扩展字符串

2 、双引号 “” 界说的字符串为可扩展字符串javahdxx,可扩展字符串里边能够运用 ${} 引证变量值,当 {} 里边只需一个变量,数组词非表达式时,{}也能够去掉

3 、三引号 ”’ ”’ 界说实例化需求的字符串为输出带格式的不行扩展字符串

def age = 16
def name = 'erdai'
/java环境变量装备/界说一个不行扩展字符串,和我门在Java中运用差不多
def str1 = 'he数组c言语llo ' + name
//界说可扩展字scala装置符串,字符串里边能够引证变量值,当 {} 里边只需一个变量时,{}也能够去掉
def str2 = "hello $name ${name + age}"
//界说带输出格式的不行扩展字符串 运用  字符来分行
def str3 = '''

hello
name
'''
//打印类型和值 下面代码我省httpclient掉了 println 办法的(),上面有讲到这种语法也是容许的
pScalarintln 'str1类型: ' + strscala是什么1.class
println 'str1输出值: ' + str1
println 'str2类scala装置型: ' + str2.class
println 'str2输出值: ' + str2
println 'str3类型: ' + str3.class
println 'str3输scala菜鸟教程出值: ' + str3
//打印作用
str1类型: class java.lang.String
str1输出值: hello实例化类 erdai
str2类型: class org.codehaus.groovy.runtime.GStringImpl
str2输出值: h实例化是什么意思ello erdai erdai16
str3类型: class java.lang.String
str3输出值:
hello
name

从上面代码咱们能够实例化类看到,str2 是 GStringImpljavascript实例化servlet类反常型的,而 str1 和 str3 是 String 类型的,那么这儿我就会有个疑问,这两种类型在相互赋值的状况下是否需求强转呢?咱们做个scalability试验在查验下:

//界说一个 String 类型的变量接纳 GStringImpl 类型的变量,并没有强转
String str4 = str2
pHTTPrintln 'str4类型: ' + str4.class
println 'str4输出值: ' + st数组指针r4
//打印类型和值
str4类型: class java.lang.String
str4输出值: hello erdai erdai16

因而咱们能够得出定论:编码的进程中,不需求特别重视 String 和 GString 的差异,编译器会帮助咱们主动转化类型

6. 不必写 get 和 set 办法

1、在咱们创立特征的时分,Groovy会http://192.168.1.1登录帮咱们主动创立 get 和http://www.baidu.com set 办法

2、当咱们只界说了一个特征的 get 办法,而没有界说这个特征,默许这个特征只读

3、咱们在使⽤政策 object.fjava根底常识点ield 来获取值或许运用 object.field = value 来赋值的时分,实例化目标是什么意思实践上会主动转而调⽤实例化servlet类反常 object.scalablegetField() 和 object.setField(value) 办法,假定咱们不想调用这个特别的 get 办法时则能够运用 .@ 直接域拜访操作符拜访特征自身

咱们来模仿1,2,3这三种状况

//状况1:在咱们https和http的差异创立特征的时分,Groovy会帮咱们主动创立 gejava名优馆在线六区thttpclient 和 set 办法
class People{
def na数组初始化me
def age
}
def people =实例化目标的关键字 new People()
people.name = 'erdai'
peoplescalar是什么意思.age = 19
println "姓名: $people.name 年岁: $people.age"scala环境装备
//打印作用
姓名: erdai 年岁: 19
//状况2 当咱们界说了一个特征的 get 办法,而没有界说这个特征,默许这个特征只读
//咱们修改一下People类
class Peo数组词ple{
def name
def getAge(){
12
}
}
def people = new People()
people.name = 'erdai'
people.age = 19
printlHTTPn "姓名: $people.namhttp 404e 年岁: $people.age"
//作业一下代码 打印作用报错了,如下:
Caught: groovy.lang.ReadOnlyPropertyException: Cannot set readoscala环境装备nly propjavascripterty: age for class: variable.People
//大约过错意思便是咱们不能修改一个只读的特征
//状况3: 假定咱们不想调用这个特别的 get 办法时则能够运用 .@ 直接域拜访操作符拜访特征自身
classjava游戏 People{
def name
def age
def gscalableetName(){
"My name is $name"
}
}
//这儿运用了命名的参数实例化类初始化和默许的结构器创立people政策,后边会讲到数组
def people = new People(name: 'erdai666')
people.age = 19
def myName = people.@name
//打印值
println myNhttp协议amescalar是什么意思
println "姓名: $people.name 年岁: $people.age"
//打印作用
erdai666
姓名: My name is erdai666 年岁: 19数组去重
//看到差异了吗?运用 people.name 则实例化类会去调用这个特征的get办法,而 people.@name 则会拜访这个特征自身

7、Class 是一等公民,悉数的 Class 类型能够省掉 .Class

/Scala/界说一个Test类
class Test{
}
//界说一个查验数组去重的5种办法class的办法,早年面的语法咱们知道,办法的参数类型是能够省掉的
def testClassjava环境变量装备(myClass){
}
//查验
testClhttp协议ass(Test.class)
testClass(Test)

8、== 和 eqScalauals

在 Groovy 中,== 就相当于 Java 的 equals,假定需求比较两个政策是否是同一个,需求运用 .ijava模仿器s()

class Peopljava模仿器e{
def name
def age
}
def people1 = new People(name: 'erdai666')
dehttp 500f people2 = new People(name: 'erdai666')
printlhttpclientn("people1.name == people2.name is: " + (people1.name == peoplehttps和http的差异2.name))
println("people1 is people2 is: " + people1.is(people2))
//打印作用scala怎样读
people1.name == people2.name is: true
people1 is people2 is: false

9、Scala运用 assert 来设置断语,当断语的条件为 false 时scalar是什么意思,程序将会抛出反常

assert  2 **scala教程 4 == 15
//作业程序,报数组指针错了,作用如下javaee
Caught: Assertion failed:
assejava根底常识点rt  2 ** 4 == 15
|    |
16   false

10、支撑 ** 次方运算符

assert  2 **实例化 4 == 16

11、简练的三元java怎样读表达式

//在java中,咱们会这么写
String str = obj != null ?实例化servlet类反常 obj : ""
//在Groovy中,咱们能够这样写,?: 操作符标明假定左面作用不为空则取左面的值,不然取右边的值
String str = obj ?: ""

12http协议、简练的非空判别

//在java中,咱们可能会这么写
ifjava怎样读(obj != null){
if(obj.group != null){
if(obj.group.artifjava环境变量装备act != null){
//do something
}
}
}
//在Groovy中,咱们能够这样写 ?. 操作符标明假定当时调用政策为空就不实行了
obj?.gro数组去重up?.artifact

13、强健的 Switch

在 Groovy 中,switch 办法变得愈加活络,强健,能够同时支撑更多的参数类型,比在 Java 中增强了许多

def result = 'erdai666'
switch (result){
case [1,2,'数组的界说erdai666']:
println "匹配到了result"
bre实例化目标ak
default:
println 'default'
break
}
//打印作用
匹配http 302到了result

14、判别是否为 null 和 非运算符

数组词 Groovy 中,悉数类型都javaee能转成布尔值,比方 nul实例化是什么意思l 就相当于0或许相当于false,其他则相当于true

//在 J数组词ava 中,咱们会这么用
if (name != nul实例化需求l &amscala环境装备p;&amphttp 302; name.leng实例化一个类tjava名优馆在线六区h > 0) {
}
//在 Groovy 中,能够这么用,假定name为 null 或 0 则回来 false,scala怎样读不然回来true
if(name){
}
//非运算符 erdai 这个字符串为非 null ,因而为truejava环境变量装备,而 !erdai 则为false
assert (!'erdai') = false

15、能够运用 Number 类scala环境装备去代替 flhttp 500oat、double 等类型,省去考虑精http 404度的费事

16、默许是 public 权限

默许状况下,Groovy 的 class 和 办法都是 public 权限,所以我scala教程们能够省掉 pubhttp://192.168.1.1登录lic 要害字,除非咱们想运用 private 修饰符

class Server {
String toString() { "a server" }
}

17、运http://192.168.1.1登录用命名的参数初始化和默许的结构器

Groovy中,咱们在创立一个政策实例的javascript时分,能够直接在结构办法中经过 key value 的办法给特征赋值,而不需求去写结构办法,说的有点抽象,上代码感受一下:

//界说一个people
class People{
def name
def age
}
//咱们能够经过以下几种办法去实例化一个java环境变量装备政策,留神咱们People类里边没有写任何一个结构办法哦
def people1 = new People()
def people1 = new People(age: 15)
def people2 = new People(name: 'erdai')
def people3 = new People(age: 15,name: 'erdai')

18、运用 with 函数操作同一个政策的多个特征和办法

with 函数接纳一个闭包,闭包下面会讲,闭包的参数便是当时调java游戏用的政策

class People{
def name
def agescalar是什么意思
void running(){
println '跑步'
}
}
//界说一个 peojavaeeple 政策
def people = new People()
//调用 with 函数 闭包参数即为peopeo 假定闭包不写参数,默许会有一个 it 参数
people.with{
name = "erdai"
age = 1实例化需求9
println "$name $age"
r数组unning()数组的界说
}
//打印作用
erdai 19
跑步

19、反常捕获

假定你真实不想关心 tr数组公式y 块里抛出何种反常,你能够简略javascript的捕获悉数反常,而且能够http协议省掉反常类型:

//在 javahttp署理 中咱们会这样写
try {
// ...
} caScalatch (Exception e) {
// do something
}
//在 Groovy 中,咱们能够这样写
try {
// ...
} catch (any) {
// do something
}

上面 Gro实例化数组ovy 的写法其实便是省掉了参数类型,实践上 any 的参数类型也是 Exception, 并不包含 Throwable ,假定你想捕获悉数的反常,你能够清晰捕获反常的参数类型

四、Groovy 闭包

在 Groovy 中,闭包非常的重要,因而单独用一个模块来讲

1、闭包界说

引证 Groovyhttp署理 官方对闭包的界说:A closure in Groovy is an open, ascala菜鸟教程nonymous, block of code that can take arguments, return a value and be assi实例化gned to a variable. 翻译过来便是:Groovy 中的闭包是一个翻开的、匿名的代码块,它能够接受参数、回来值并将值scalable赋给变量。 粗浅的讲,闭包能够作为方scala菜鸟教程法的参数和回来值,也能够作为一个变量而存在,闭包本质上便是一段代码块,下面咱们就由浅入深的来学习闭包

2、闭包声明

1、闭包http协议根柢的语法结构:外面一对大括号,接着是声明参数,参数类型可省掉,在是一个 -> 箭头号,毕竟便是闭包体里边的内容

2、闭包也能够不界说参数,假定闭包没界说参数的实例化目标的关键字话,则隐含有一个参数,这个参数姓名叫 it

//1
{ params ->
//do something
}scala是什么
//2
{
//do something
}

3、闭包调用

1、闭包能够经过 .call 办法来调用

2、闭包能够直接用括号+参数来调用

//界说一个闭包赋值给 closure 变量
def closure = { pJavaarams1,params2 ->
params1 + params2
}
//闭包调用办法1: 闭包能够经过 .call 办法来调用
def result1 = closure('erdai ','666')
//闭包调用办法2: 闭包能够直接用括号+参数来调用
def resScalault2 = closure.call('erdai ','777')
//打印值
println result1
println result2
//打印作用
erdai 666
erdai 777
//http://www.baidu.com界说一个无参闭包
def closure1 =scalability {
println('无界说参数闭包')
}
closure1() //或许调用 closure1.call()
//打印作用
无界说参数闭包

4、闭包进阶

1)、闭包中的要害变量

每个数组去重闭包中都含有 this、owner 和 delegate 这三个内置政策,那么这三个三个内置政策有啥差异呢?咱们用代码去验证一下实例化需求

留神

1、getTh实例化类isObject() 办法 和 thisObject 特征等同于 this

2、getOwner数组函数的使用办法() 办法 等同于 owner

3、gJavaetDelegate() 办法 等同于 delegate

这些去看闭包的源码你就会有深化的体会

1、咱们在 GroovyGrammar.groovy 这个脚本类中界说一个闭实例化包打印这三者的值看一下:

//界说一个闭包
def outerClosure = {
println "this: " + this
println "owner: " + owner
println "delegate: " + delegate
}
//调用闭包
outerClosure.call()
//打印作用
this: variable.GroovyGrammar@39dcf4b0
owner: variable.GroovyGrammar@39dcf4b0
delegate: variable.GroovyGrammar@39dcf4b0
//证明当时三者都指向了GroovyGrammar这个脚本类政策

2、咱们在这个 GroovyGrammar.groov数组排序y 这个脚本类中界说一个类,类中界说一个闭包数组指针,打印看下作用:

//界说一个 OuterClass 类
class OuterClass {
//界说一个闭包
def outerClosuscala怎样读re = {
println "this: " + this
println "owhttp协议ner: " + owner
println "delegate: " + delegate
}
}
def outerClass = new OuterClass()
outerClass.outerClosure.call()
//打印作用如下:
this: variable.OuterClass@1992eaf4
owner: variable.OuterClass@1992eaf4
delegate: varihttp://www.baidu.comable.OuterClass@1992eaf4
//作用证明这三者都指向了当时 OuterClass 类政策

3、咱们在 GroovyGrammar.groovy 这个脚本类中,界说一个闭包,闭包中在界说一个闭包,打印看下作用:

def outerClosure = {
def innerClosure = {
println "this: " +Scala this
println "owner: " + owner
println "HTTPdelegate: "scala装置 + delegate
}
innerClosure.数组去重call()
}
println outerClosure
outerClosure.call()
//打印作用如下
variable.GroovyGrammar$_run_closure4@64beebb7
this: variable.GroovyGrammar@5b58ed3c
owner: variable.GroovyGrammar$_run_closure4@64beebb7
delegate: variable.GroovyGrammar$_run_closure4@64beebb7
//作用证明 this 指向了当时GroovyGrammar这个脚本类政策 owner 和 delegate 都指向了 outerClosure 闭包政策

咱们整理一下上面的三种状况:

1、闭包界说在GroovyscalabilityGrammar.g实例化目标是什么意思ro实例化目标ovy 这个脚本类中 this owner delegate 就指向这个脚本类政策

2、我在这个脚本类java根底常识点中创立了一个 OuterClass 类,并在他里间隔说了一个闭包,那么此刻 this owner delegate 就指向了 OuterClass 这个类政策

3、我在 GroovyGrammar.groovy 这个java名优馆在线六区脚本类中界说了一个闭包,闭包中又界说了一个闭包,this 指向了当时GroovyGrammar这个脚本类政策, owner 和 delegate 都指向了 outerClosure 闭包政策

因而咱们能够得到定论:

1、this 永久指向界说该闭包最近的类政策,就近准则,界说闭包时,哪个类离的最近就指向哪个,我这实例化英文儿的离得近是指界说闭包的这个类,包含内部类

2、owner 永久指向定数组去重的5种办法义该闭包的类政策或许闭包政策,断章取义,闭包只能界说在类中或许闭包中

3、delegatehttpwatch 和 owner 是相同的http 302,咱们在闭包的源码中能够看到,owner 会把自己的值赋给 delegate,但同时 delegate 也能够赋其他值

留神:在咱们运用 this , owner , 和java环境变量装备 delegate 的时分, this 和 owner 默许是只读的,咱们外部批http://www.baidu.com改不了它,这点在源码中也有体现,但是能够对 delegate 进行操作

2)、闭包托付战略

下面咱们就来对修改闭包的 delegate 进行实操:

//创数组公式建一个香蕉scala教程
class Banana{
def name
}
//创立一个橘子类
c实例化数组lass Orange{
def name
}
//界说一个香蕉政策
def banana = new Orange(name: '香蕉')
//界说一个橘子政策
def orange = new Orange(name: '橘子')
//界说一个闭包政策
def closurscala教程e = {
//打印值
println delegascala是什么te.name
}
//调用闭包
closure.ca数组初始化ll()
//作业一下,发现作用报错了,如下
Caught: groovy.lang.MissingPropertyException: No such property: name for class: variable.Groovyjava名优馆在线六区Grammar
//大致意思便是GroovyGrammar这个脚本scalable类政策没有这个 name 政策

咱们来剖析下报错的原因原因,剖析之前咱们要了解一个常识点:

闭包的默许托付战略是 OWNER_FIRST,也便是闭包会先从 owner 上寻觅特征或办法,找不到则在 dejavascriptlegate 上寻觅

1、closure 这个闭包是生明在 GroovyGrammar 这个脚本类傍边

2、依据咱们之前学的常识,在不改动 delegate 的状况下 dhttp协议elegate 和 owner 是相同的,都会指实例化servlet类反常向 GroovyGrammar 这个脚本类政策

3scalar、GroovyGrammar 这个脚本类政策,依据闭包默许托付战略,找不到 name 这个特征

因而报错了,知道了报错原因,那咱们httpclient就修改一下闭包的 delegate , 仍是上面那段代码,添加如下这句代码:

//修改闭包的delegate
closurscala菜鸟教程e.delegate = orange
//咱们在作业一下,打印作用:
橘子

此刻闭包的 delegate 指向了 orange ,因而会打印 orange 这个政策的 name ,那么咱们把 closure 的 delegate 改为 banana,必定就会打印香蕉了

//修改闭包的delegate
closure.delegate = banana
//咱们在作业一下,打印作用:
香蕉

3)、深化闭包托付战略

//界说一个 ClosureDscala菜鸟教程epth 类
class ClosujavaeereDepth{
//界说一个变量 str1 赋值为 erdai666
def str1 = 'erd数组函数的使用办法ai666'
//界说一个闭包
def outerClosure = {
//界说一个变量 str2 赋值为 er实例化数组dai777
def str2 = 'erdai777'
//打印st实例化数组r1 剖析1
println str1
//闭包中在界说一个闭包
def innerClosure =http://192.168.1.1登录 {
//剖析2
println str1
println str2
}
//调用内部这个闭包
innerClosure.java根底常识点call()
}
}
//创立 ClosureDepth 政策
def closureDepth = new ClosureDepth()
//调用外部闭包
closureDepth.outerClosure.call()
//作业程序,打印作用如下
erdai666
erdai666
erda实例化servlet类反常i777

上面代码注释写的很清楚,现在咱们来要害剖析下剖析1和剖析2处的打印值:

java名优馆在线六区析1:

剖析1处打印了 str1 , 它处于 outerClosjava怎样读ure 这个闭包中,此刻 outerClosure 这个闭包的 owner , delegate 都指向了 ClosureDepth实例化目标是什么意思 这个类政策,因而scalar ClosureDepth 这个类政策的特征和办法咱们就都能调用到,因而剖析1处会打印 erdai666

剖析2:

剖析2处打印了 str1和 str2,它处于 innerClosure 这个闭包中,此刻 innerClosure 这个闭包的 owner 和 delegate 会指向 ojava游戏uterClosurhttp://192.168.1.1登录e 这个闭包政策,咱们会发现 outerClosure 有 str2 这个特征,但是并没有 str1 这个特征,因而 outerClosure 这个闭包会向它的 owner 去寻觅,因而会找到 ClosureDepth 这个类政策的 str1 特征,因而打印的 s实例化数组tr1 是ClosureDepth 这个类政策中的特征,打印的 str2 是outerClosujava根底常识点re 这个闭包中的特征,所以剖析2处的打印作用分别是 erdai666 erda实例化目标是什么意思i777

上面的例子中没有显式的给 delegate 设置一个接纳者,但是不管哪层闭包都能成功拜访到 str1、str2 值,这是由于默许的解析托付战略在发挥作用,Groovy 闭包的托付战略有http 404如下几种:

  1. OWNER_FIRST:默许战略,首先从 ojavascriptwner 上寻觅特征或办法,找不到则在 dscala菜鸟教程elegate 上寻觅
  2. DELEGATE_FIRST:和上面相反,首先从 delegate 上寻觅特征或许办法,找不到则在 owner 上寻觅
  3. OWNER_ONLY:只在 owner 上寻觅,delegate 被scalability疏忽
  4. DELEGATE_ONLY:和上面相反,只在 delegat实例化数组e 上寻觅,owner 被疏忽
  5. TO_SELF:高级选项,让开发者自界说战略,有必要要自界说结束一个 Closhttp署理ure 类,一般咱们这种玩家用不到

下面咱们就来修改一下闭包的托付战略,加深了解:

class实例化目标的关键字 People1{
def name = '我是People1'
def action(){
println '吃饭'
}
def closure = {
println name
action()
}
}
class People2Scala{
def name = '我是People2'
de实例化是什么意思f action(){
println '睡觉'
}
}
def people1 = new People1()
def people2scala菜鸟教程 = new People2()
phttp协议eople1.cjava环境变量装备losure.delegate = people2
people1.closure.call()
//作业下程序,打印作用如下:
我是People1
吃饭

what? 这是啥状况,我不是修改了 delegate 为 people2 了,怎样打印作用仍是 people1 的?那是由于咱们疏忽了一个点,没有修改闭包托付战略,他默许是 OWNER_FIRST ,因而咱们http://www.baidu.com修改一下就好了,仍是上面这段代码,添加一句代码如下:

people1.closure.resolveStrategy = Closure.DELEGATE_FIRST
//作业下程序,打印作用如下:
我是P实例化目标是什么意思eople2
睡觉

到这儿,相信你对闭包了解的差不多了,下面咱们在看下闭包的源码就实例化目标的关键字完美HTTP

4)、闭包 Closure 类源码

仅贴出要害源码

public abstract class Closure<V> extends GScalaroovyObjectSupport implements Cloneablhttp 302e, Runnable, GroovyCallable<V>,数组去重的5种办法 Sejavahdxxrializable {
/**
* 了解的一堆闭包托付署scalar是什么意思http 404战略
*/
public static finhttp 302al int OWNER_FIRST = 0;
public static final int DELEGATE_FIRST = 1;
public static final int OWNER_ONLY = 2;
public static final inthttp://www.baidu.com DELEGATE_ONL实例化目标Y = 3;
public static final int TO_SELF = 4;
/**
* 闭实例化英文包对应的三个托付政策 thisObject 对应的便是 this 特征,都是用 private 修饰的,外界拜访不到
*/
private Object delegate;
private Object owner;
private Object thisObject;
/**
* 闭包托付战略
*/
private int resolveStrategy;
/**
* 在闭包的结构方数组初始化法中:
* 1、将 resolveStrategy 赋值为0,也是就默许托付战略OWNER_FIRscala教程ST
* 2、this实例化目标Object ,owner ,delegate都会被赋值,delegatjava面试题e 赋的是 owner的值
*/
public Closure(Object owner, Object thisObject) {
this.resolveStrategy = 0;
this.owner = owner;
this.delegate = owner;
this.thisObject = thisScalaObjehttp 404ct;
CachedClosureClass cachedCla实例化目标的关键字ss = (Cachedjava怎样读ClosureClass)ReflectionCscalar是什么意思ache.getCachedClass(this.getClass());
this.param数组指针eterTypes = cache实例化一个类dClass.getPar数组c言语ameterTypes();
this.maximumNumberOfParameters = cachescala环境装备dClass.getMaximumNumberOfParametjavahdxxers();
}
/**
* thisObject 只供给了 get 办法,且 thisObject 是用 private 修饰的,因而 thisObjec数组初始化t 即 this 只读
*/
public Object getThisObject() {
rescala装置turn this.thisObject;
}
/**
* owner 只供给了 get 办法,且 owner 是用 private 修饰的,因而 owner 只读
*/
public Object getOwner() {
return this.owner;
}
/**
* delegate 供给了 get 和 set 办法,因而 delegate 可读写
*/
public Object getDelegate() {java怎样读
return this.delegate;
}
public void setDelegate(Ohttp署理bject delegate) {
this.delejava名优馆在线六区gate = delegajava面试题te;
}
/**
* 了解的托付战略设置
*/
pubScalalic void setResolveStratehttp 500gy(int resolveStrategy) {
this.rescala怎样读solveStrategy = resolveStrategy;
}
public int getResolveStrategy() {
return resolveStrategy;
}
}

到这儿闭包相关的常识点就都讲完了,但是,但是,可scala教程是,重要的工作说三遍:java环境变量装备们运用闭包的时分,怎样去供认闭包的参数呢?,这个真的很蛋疼,作为 Android 开发者,在运用 AndroidStudio 进行 Gradle 脚本编写的时分,真的是非常不和睦,上面我讲了能够运用一个小技巧去处理这个问题,但是这种状况是在你知道要scala环境装备运用一个 Api 的状况下,比方你知道 Map 的 each 办法能够遍历,但是你不知道参数,这个时分就能够去运用。那假定你连 Api 都不知道,那就愈加不知道闭包的参数了,因而要处理这种状况,咱们就有必要去查阅 Groovy 官方文档:

www.groovy-lang.org/api.html

docs.groovy-lang.org/latest/html…

五、Groovy数据结构

经过这个模块的学习,我会结合具体的例子来说明怎样查阅文档来供认闭包中的参数,在讲 MapJava 的时分我会讲到

Groovy 常用的数据结构scala教程有如下 四种:

  • 1)、数组
  • 2)、List
  • 3)、Map
  • 4)、Range

1、数组

实例化目标的关键字 Groovy 中运用 [ ] 标明的是一个 List 集结,假定要界说 Array 数组,咱们就有必要强制指定为一个数组的类型

//在 Java 中,咱们一httpclienthttp署理会这样去界说一个数组
String[] javaArray = ["Java", "Groovy", "Android"]
//在 Groovy 中,咱们一般会运用 as 要害字界说数组
def groovyArra数组c言语y =实例化目标 ["Java", "Groovy", "Android"] as Striscala装置ng[]

2、List

1)、列表http协议集结界说

1、List 即列表集结,数组词对应 Java 中的 List 接口,一般用 Arrayhttps和http的差异List 作为真实的结束类

2、界说一个列表集结的办法有点像 Java 中数组初始化界说数组相同

3、集结元素能够接纳任意http://192.168.1.1登录的数据类型

//在 Groovy 中界说数组函数的使用办法的集结默许便是对应于 Java 中 ArrayLis实例化类t 集结
d实例化是什么意思ef li数组公式st1 = [1,2,3java环境变量装备]
//打印 list 类型
printjavahdxx list1.cscala是什么lass
//打印作用
class javascalar是什么意思.util.ArrayList
//集结元素能够接纳任意的java游戏数据类型
def list2 =scala怎样读 ['erdai666', 1, true]

那么问题来了,假定我想界说一个 LinkedList 集结,要怎样做呢?有两种办法:

1、经过 Java 的强类型办法去界说

2、经过 as 要害字来指定

//办法1:经过 Java 的强类型办法去界说http 404
LinkedList list3实例化目标是什么意思 = [4,http署理 5,HTTP 6]
//办法2:经过 as 要害字来指定
def listhttpwatch4 = [1, 2http署理, 3] as LinkedList

2)、列表集结增修改查

def list = [1,2,3]
//-----------------scalable--------- 添加元素 ---------------------------------
//有以下几种办法
list.add(20)
list.leftShift(20)
list << 20
//-------------------------- 删去元素 ---------------java怎样读------------------
//依据下标移除元素
list.remove(0)
//------实例化英文------实例化是什么意思-------------- 修改元素 ------scala菜鸟教程----------数组初始化------实例化需求-----------
//依据下标修改元素
list[0] = 100
//-------------------------- 查询元素 ---------------------------------
//调用闭包的 find 办法,办法中接纳一个闭包,闭包的参数便是 list 中的元素
list.find {
println it
}

列表集结 Api 挺多的,关于一些其他Api,运用到的时分自行查阅文档就好了,我会在下面讲httpclient Map 的时分演示查阅 Api 文档供认闭包的参数

3、Map

1)、界说

1、Map 标明键-值表,其底层对应 Javhttpwatcha 中的 LinkedHashMap

2、Map 变量由实例化英文[:]界说,冒号左面是 key,scala是什么右边是 Value。key 有必要是字符串,value 能够是任何政策

3、Map 的 key 能够用 ” 或 “” 或 ”’ ”’包起来,也能够不必引号包数组c言语起来

def mahttpclientp = [a: 1, 'b': t实例化类rue, "c" : "Groovy", '''d''' : '''ddd''']

2)、Map 常用操作

这儿罗列一些 Ma数组的界说p 的常用操作,一些其他的 Api 运用到的时分自行查阅文档就好了

//---scalar是什么意思-----------实例化是什么意思-------------- Map 中元素拜访操作 -----实例化目标的关键字-----------
/**
* 有如下三种办法:
* 1、map.key
* 2、map实例化是什么意思[keyhttp://192.168.1.1登录]
* 3、map.get(ket)
*/
println map.a
println map['b']
println map.get('c')
//打印作用
1
true
Gr数组oovy
//---------------------------- Map 中添加和修改元素 --------scalable--实例化类---------
//假定当时 key 在 map 中不存在,则增实例化是什么意思加该元素,假定存在则修改该元素
map.put('key','value')
map['key'] = "value"

3)、Map 遍历,演示查阅官方文档

http署理在我要去遍历 map 中的元素,但是我不知道它的 Api 是啥,那这个时分就要去查官方 Api 文档了:

docsjava模仿器.groovy-lang.org/latest/html…

咱们查到 Map 有 each 和 ea数组词chWithIndex 这两个 Api 能够去实行遍历操作,接着点进去看一眼

经过官方文档咱们能够发现: each 和 eachWit实例化是什么意思hIndex 的闭包参数仍是不实例化目标供认的,假定咱们运用 each 办法,假定传递给闭包是一个参数,那么它就把 entry 作为参数,假定咱们传递给闭包是两个参数,那么它就把 key 和 value 作为参数,java环境变量装备eachWithIndex 比 each 多了个 index 下标算了.

那么咱们现在就运用以下这两scala是什么个 Api :

//下面为了打印输出的格式清楚,做了一些额定的操作
def map = [a: 1, 'b': true, "c" :http 500 "Groovy", '''d''' : '''ddd''']
map.each {
print "$it.key $it.value t"
}
println()
map.each {key,value ->
print "$kjavascriptey $value t数组去重的5种办法"
}
println()
map数组指针.eachWithIndex {entry,index ->
print "$entry.key $entry.value $ihttpwatchndex t"
}
println()
map.eachWithIndex { key,value,ind数组词ex ->
print "$key $value $index t"
}
//打印作用
a 1 	b true 	c Groovy 	d ddd
a 1 	b true 	c Groovy 	d ddd
a 1 0 	b true 1 	c Groovy 2 	d ddd 3
a 1 0 	b true 1 	c Groovy 2 	d ddd 3

4、Range

Range 标明规划,它其实是 List 的一种拓展。其由 begin 值 + 两个点 + end 值标明。假定不想包含毕竟一个元素,则 begin 值 + 两个点 + < + end 标明。咱们能够经过 aRange.from 与 aRange.to 来获对应的间隔元素,实践操作感受一下:

//界说一个两头都是闭区间的规划
def range = 1..10
range.ea实例化一个类ch {
print it + " "
}
//打印值
1 2 3 4 5 6 7 8 9 10
//假定不想包含毕竟一个元素
def range1 = 1..&实例化英文lt;10
range1.each {
print it + " "
}
//打印作用
1 2 3 4 5 6 7 8 9
//打印头尾间隔元素
println "$range1.from $range1.to"
//打印作用
1 9

六、Groovy 文件处理

1、IO

一些 IO 常用的 Api 操作,咱们直接上代码看作用,代码会写上清楚的注释:

准备作业:我在当时脚本文件的同级目录下创立一个 te实例化目标的关键字stFile.txt 文件,里边随意先写入一些数组的界说字符实例化需求串,如下图:

下面咱们初步来操scala是什么作这个文件,为了闭包的可读性,我数组公式会在实例化闭包上加上类型和参数:

//-------------------------------1、文件定位 --------------------http署理------------
def file = new File('testFile.txt')
//-----------------------2、运用 eachLine Api 每次读取一行, 闭包参数是每一行的字符串------------
file.eachLine { String line ->
prin实例化目标是什么意思tln line
}
//打印作用
erdai666
erdai777
erdai888
//------------------------3、获取输入流,输出流读文件和写文件---------------------scala装置---http 500---------
//获取输入流读取文件的每一行
/httpclient/1
file.withInputStream { InputStream inputStream ->
inputStream.eachLine { String it ->
println it
}
}
//2
file.withReader { Buf数组公式feredReader it ->
it.readLines().each { String it ->
println it
}
}
//打印作用
erdhttp://192.168.1.1登录ai666
erdai777
erdscalar是什么意思ai888
//获取输出流将字符串写入文件数组排序 下面这两种办法写入的文件内容会把之前的内容给掩盖
//1
file.withOutputStream { OutputStream outputSt数组初始化ream ->
outpu实例化tStream.write("erdai999".getBytes())
}
//2
file.withWriter { BufferedWriter it ->
it.write('erdai999')
}
//------------------------4、经过输入输出流结束文件拷贝功用-----javaee-----------------scala装置-----------
//1、经过 withOutputStream wihttp署理thInpu数组c言语tStreajavaeem 结束文件拷贝
def targetFile = new File('testFile1.txt')
targetFile.withOutputStream { Outpujava怎样读tStream outputStream ->
file.wjava面试题ithInputStream { InputStream inputStream -实例化英文>
outputStream << inputStream
}http 302
}
//2、经过 withReader、withWriter 结束文件拷贝
targetFile.withWriter {BufferedWriter bufferedWriter ->
file.withReader {BufferedReader bufferedReaderjava面试题 ->
bufScalaferedReader.eachLine {St实例化servlet类反常ring line ->
bufferedWriter.write(line + "rn")
}
}
}

2、XML 文件操作

1)、http://192.168.1.1登录解析 XML数组指针 文件

//界说一个带格式的 xml 字符串
dscala怎样读escalarf xml = '''实例化需求
<response>
<value>
<books id="1" classification="android">
<book available="14" id="2">
<title>榜首行代码</title>
<author id="2">郭霖</author>
</book>
<book available="13" id="3">
<title>Android开发艺术根究</title&实例化类gt;
<author id="3">实例化是什么意思任玉刚</author>
</book>
</books>
</value&scalabilitygt;
</response>scalar
'''
//创http 500建 XmlSlurper 类政策,解析 XML 文件首要凭仗 XmlSlurper 这个类
def xmlSlurper = new XmlSlurper()
//解析 mxl 回来 response 根结点政策
def response = xmlSlurper.parseText(xml)
//打印一些作用
println response.value.books[实例化类0].book[0].title.t数组的界说ext实例化需求()
pri实例化目标是什么意思ntln response.val数组c言语ue.books[0].book[0]Java.author.text()
//打印作用
榜首行代码
郭霖
//1、运用迭代器解析
response.数组公式valu数组初始化e.books.each{ books ->
books.book.each{ book ->
println bookhttps和http的差异.title
println数组指针 book.author实例化是什么意思
}
}
//打印作用
榜首行代码
郭霖
Android开发艺术根究
任玉刚
//2、深度遍历 XML 数数组指针
def str1 = response.depthFirst().findAll { bookjava怎样读 ->
return book.author == '郭霖'
}
println str1
//打印作用
[榜首行代码郭霖]
//java怎样读3、广度scala教程遍历 XML 数据
def str2 = response.value.books.children().findAll{ node -&gtjava游戏;
noscala教程de.name() == 'book' && node.@id == '2'
}.collect { node ->
"$node.title $node.author"
}
println str2
//打印作用
[榜首行代码 郭霖]

2)、生成 XML 文件

上面咱们运用 XmlSlurper 这个类解析了 XML,现在咱们凭仗 MarkupBuilder 来生成 XML ,代码如下:

/**
* <response>
*      <value&scala菜鸟教程gt;
*          <books id实例化目标="1" classification="android">
*              <book available="14" id="2">
*                 <title>榜首行代码</title>
*                 <author id="2">郭霖</author&实例化数组gt;
*             </book&实例化数组gt;
*             <book available="13" id=scalar是什么意思"3">
*                 &lhttp署理t;title>Androihttp 404d开发艺术根究</title>
*                 <author id="3">任玉刚</author>
*             </book>
*         <http 500/books>
*     </value>
* </response>
*/
//办法1:经过下面这种办法 就能够结束上数组c言语面的作用,但是这种办法有个害处,数据都java怎样读是写死的
def sw = new StringWriter()
def xmlBuilder = new MarkupBuilder(sw)
xmlBuilder.response{
value{
books(id: '1',classificatiscalaron: 'android'){
book(available: '14',id:实例化是什么意思 '2'){http://192.168.1.1登录
title('榜首行代码')
author(id: '2' ,'郭霖')
}
book(available: '13',id: '3'){
title('Android开发艺术根究')
author(id: '3' ,'任玉刚')
}
}
}http 302
}
println sw
//办法2:将 XML 数据对应创立相应的数据模型,就像咱们解析 Json 创立相应的数据模型是相同的
//创立 XML 对应数据模型
class Response {
def value数组去重 = new Value()java环境变量装备
cl数组去重的5种办法ass Value {
def books = new Books(id: '1', classification: 'android')
class Books实例化类 {
def id
def classification数组的界说
def book = [new Book(available: '14', id: '2', title: '榜首行代码', authorId: 2, author: '郭https和http的差异霖'),
new Book(available:数组的界说 '13', id: '3',http://192.168.1.1登录 title: 'Android开发艺术根究', author实例化servlet类反常Id: 3, author: '任玉刚')]
class Bookhttp署理 {
def available
def id
def title
def authorId
def author
}
}
}
}
//创立 response 政策
def response = new Resjavahdxxponsehttpwatch()
//构建 XML 
xmlBuilder.response{
value{
books(id: response.value.books.id,classification: response.value.books.classification){
response.v数组排序alue.books.book.each{
def book1 = it
book(available: it.avai实例化需求lable,id: it.id){
tithttp协议le(book1.title)
author(authorId: book1.authorId,book1.author)
}
}
}
}
}
println sw

3、Json 解析

Json解析首要是经过 JsonSlurper 这个类结束的,这数组公式样咱们在写插件的时数组词分就不需求额定引进第三方的 Json 解析库了,其示scalability例代码如下所示:scala装置

//发送央求获取服务器响应的数据
def response = getNetWorkData("https://www.wanajavaeendroid.com/banner/json")
println response.data[0].desc
println response.data[0].imagejava模仿器Path
def getNetWorkData(String url){
def connect = new URL(url).openConnection()
connect.setRequestMethod("GET")
//这个会堵塞线程 在Android中不能这样操作 但是在桌面程序是能够的
connect.connect()
def response = connect.content.text
//json转实体政策
def jsonSlurper = new JsonSlurper()
jsonSlurper.parseText(response)
}
//打HTTP印作用
扔物线
https://wanandroid.com/blogimgs/8a0131ac-05b7-4b6c-a8d0-f43867http 3028834ba.png

7、总结

在本篇文章中,咱们首要介绍了以下几个部分:

1、一些关于 Gradle ,Groovy 的问实例化英文

2、java面试题树立 Groovy 开发环境,创立一个 Groovy 工程

3、解说了 Groovy 的一些根底语法

4、对闭包进行了深化的解说

5、解说了 Groovy 中的数据结构和常用 Api 运用,并以 Map 举例,查阅官方文档去供认 Api 的运用和闭包的参数

6、解说了scala教程 Groovy 文件相关的处理

学习了 Groovy ,关于咱们后续自界说 Gradle 插件迈出了要害的一步。其次假定你学习过 Kotlin ,你会发现,它们的语法非常的类似,因而关于后续学习 Kotlin 咱们也能够快速去上手。

参阅和引荐

深度根究 Gradle 主动化构建技术(二、Groovy 筑基篇

Gradle 爬坑攻略 — 概念初解、Grovvy 语法、常见 API

Groovy 本质初探及闭包特性原理总结

Gradlscala怎样读e从实例化入门到实战 – Groovy根底

慕课网之Gradle3.0主动化项目构建技术精讲+实战

全文到此,原创不易,欢迎点赞,保藏,谈论和转发,你的认但是我创造的动力