本文首发于微信公众号「刘望舒」
原文连接:Groovy快速入门看这篇就够了html
在前面咱们学习了为何如今要用Gradle?和Gradle入门前奏两篇文章,对Gradle也有了大概的了解,这篇文章咱们接着来学习Groovy的基础,要想学好Gradle,Groovy是必需要掌握的。Groovy仅凭一篇文章是介绍不完的,这里会带你们快速的入门Groovy,讲解Groovy和Java不一样的部分,想要更多了解Groovy能够查看Groovy官方文档和Groovy API文档。前端
Groovy是Apache 旗下的一种基于JVM的面向对象编程语言,既能够用于面向对象编程,也能够用做纯粹的脚本语言。在语言的设计上它吸纳了Python、Ruby 和 Smalltalk 语言的优秀特性,好比动态类型转换、闭包和元编程支持。 Groovy与 Java能够很好的互相调用并结合编程 ,好比在写 Groovy 的时候忘记了语法能够直接按Java的语法继续写,也能够在 Java 中调用 Groovy 脚本。比起Java,Groovy语法更加的灵活和简洁,能够用更少的代码来实现Java实现的一样功能。java
Groovy的代码能够在Android Studio和IntelliJ IDEA等IDE中进行编写和调试,缺点是须要配置环境,这里推荐在文本中编写代码并结合命令行进行调试(文本推荐使用Sublime Text)。关于命令行请查看Android Gradle(二)Gradle入门前奏这篇文章。 具体的操做步骤就是:在一个目录中新建build.gradle文件,在build.gradle中新建一个task,在task中编写Groovy代码,用命令行进入这个build.gradle文件所在的目录,运行gradle task名称 等命令行对代码进行调试,本文中的例子都是这样编写和调试的。程序员
Groovy中用def关键字来定义变量,能够不指定变量的类型,默认访问修饰符是public。编程
def a = 1;
def int b = 1;
def c = "hello world";
复制代码
方法使用返回类型或def关键字定义,方法能够接收任意数量的参数,这些参数能够不申明类型,若是不提供可见性修饰符,则该方法为public。 用def关键字定义方法。api
task method <<{
add (1,2)
minus 1,2 //1
}
def add(int a,int b) {
println a+b //3
}
def minus(a,b) {//2
println a-b
}
复制代码
若是指定了方法返回类型,能够不须要def关键字来定义方法。数组
task method <<{
def number=minus 1,2
println number
}
int minus(a,b) {
return a-b
}
复制代码
若是不使用return ,方法的返回值为最后一行代码的执行结果。安全
int minus(a,b) {
a-b //4
}
复制代码
从上面两段代码中能够发现Groovy中有不少省略的地方:bash
Groovy类很是相似于Java类。微信
task method <<{
def p = new Person()
p.increaseAge 5
println p.age
}
class Person {
String name
Integer age =10
def increaseAge(Integer years) {
this.age += years
}
}
复制代码
运行 gradle method打印结果为: 15
Groovy类与Java类有如下的区别:
Groovy断言和Java断言不一样,它一直处于开启状态,是进行单元测试的首选方式。
task method <<{
assert 1+2 == 6
}
复制代码
输出结果为:
Execution failed for task ':method'.
> assert 1+2 == 6
| |
3 false
复制代码
当断言的条件为false时,程序会抛出异常,再也不执行下面的代码,从输出能够很清晰的看到发生错误的地方。
Groovy支持Java的for(int i=0;i<N;i++)
和for(int i :array)
形式的循环语句,另外还支持for in loop形式,支持遍历范围、列表、Map、数组和字符串等多种类型。
//遍历范围
def x = 0
for ( i in 0..3 ) {
x += i
}
assert x == 6
//遍历列表
def x = 0
for ( i in [0, 1, 2, 3] ) {
x += i
}
assert x == 6
//遍历Map中的值
def map = ['a':1, 'b':2, 'c':3]
x = 0
for ( v in map.values() ) {
x += v
}
assert x == 6
复制代码
Groovy中的Switch语句不只兼容Java代码,还能够处理更多类型的case表达式。
task method <<{
def x = 16
def result = ""
switch ( x ) {
case "ok":
result = "found ok"
case [1, 2, 4, 'list']:
result = "list"
break
case 10..19:
result = "range"
break
case Integer:
result = "integer"
break
default:
result = "default"
}
assert result == "range"
}
复制代码
case表达式能够是字符串、列表、范围、Integer等等,由于篇幅缘由,这里只列出了一小部分。
Groovy中的数据类型主要有如下几种:
Groovy中的基本数据类型和Java大同小异,这里主要介绍下字符串类型。在Groovy种有两种字符串类型,普通字符串String(java.lang.String)和插值字符串GString(groovy.lang.GString)。
单引号字符串 在Groovy中单引号字符串和双引号字符串均可以定义一个字符串常量,只不过单引号字符串不支持插值。
'Android进阶解密'
复制代码
双引号字符串 要想插值可使用双引号字符串,插值指的是替换字符串中的占位符,占位符表达式为${}
或者以$
为前缀。
def name = 'Android进阶之光'
println "hello ${name}"
println "hello $name"
复制代码
三引号字符串 三引号字符串能够保留文本的换行和缩进格式,不支持插值。
task method <<{
def name = '''Android进阶之光 Android进阶解密 Android进阶?'''
println name
}
复制代码
打印结果为:
Android进阶之光
Android进阶解密
Android进阶?
复制代码
GString String是不可变的,GString倒是可变的,GString和String即便有相同的字面量,它们的hashCodes的值也可能不一样,所以应该避免使用使用GString做为Map的key。
assert "one: ${1}".hashCode() != "one: 1".hashCode()
复制代码
当双引号字符串中包含插值表达式时,字符串类型为GString,所以上面的断言为true。
Groovy没有定义本身的集合类,它在Java集合类的基础上进行了加强和简化。Groovy的List对应Java中的List接口,默认的实现类为Java中的ArrayList。
def number = [1, 2, 3]
assert number instanceof List
def linkedList = [1, 2, 3] as LinkedList
assert linkedList instanceof java.util.LinkedList
复制代码
可使用as操做符来显式指定List的实现类为java.util.LinkedList。 获取元素一样要比Java要简洁些,使用[]
来获取List中具备正索引或负索引的元素。
task method <<{
def number = [1, 2, 3, 4]
assert number [1] == 2
assert number [-1] == 4 //1
number << 5 //2
assert number [4] == 5
assert number [-1] == 5
}
复制代码
注释1处的索引-1是列表末尾的第一个元素。注释2处使用<<
运算符在列表末尾追加一个元素。
建立Map一样使用[]
,须要同时指定键和值,默认的实现类为java.util.LinkedHashMap。
def name = [one: '魏无羡', two: '杨影枫', three: '张无忌']
assert name['one'] == '魏无羡'
assert name.two == '杨影枫'
复制代码
Map还有一个键关联的问题:
def key = 'name'
def person = [key: '魏无羡'] //1
assert person.containsKey('key')
person = [(key): '魏无羡'] //2
assert person.containsKey('name')
复制代码
注释1处魏无羡的键值是key这个字符串,而不是key变量的值 name。若是想要以key变量的值为键值,须要像注释2处同样使用(key),用来告诉解析器咱们传递的是一个变量,而不是定义一个字符串键值。
Groovy中的闭包是一个开放的、匿名的、能够接受参数和返回值的代码块。 定义闭包 闭包的定义遵循如下语法:
{ [closureParameters -> ] statements }
复制代码
闭包分为两个部分,分别是参数列表部分[closureParameters -> ]
和语句部分 statements 。 参数列表部分是可选的,若是闭包只有一个参数,参数名是可选的,Groovy会隐式指定it做为参数名,以下所示。
{ println it } //使用隐式参数it的闭包
复制代码
当须要指定参数列表时,须要->
将参数列表和闭包体相分离。
{ it -> println it } //it是一个显示参数
{ String a, String b ->
println "${a} is a ${b}"
}
复制代码
闭包是groovy.lang.Cloush类的一个实例,这使得闭包能够赋值给变量或字段,以下所示。
//将闭包赋值给一个变量
def println ={ it -> println it }
assert println instanceof Closure
//将闭包赋值给Closure类型变量
Closure do= { println 'do!' }
复制代码
调用闭包 闭包既能够当作方法来调用,也能够显示调用call方法。
def code = { 123 }
assert code() == 123 //闭包当作方法调用
assert code.call() == 123 //显示调用call方法
def isOddNumber = { int i -> i%2 != 0 }
assert isOddNumber(3) == true //调用带参数的闭包
复制代码
Groovy的 I/O 操做要比Java的更为的简洁。
咱们能够在PC上新建一个name.txt,在里面输入一些内容,而后用Groovy来读取该文件的内容:
def filePath = "D:/Android/name.txt"
def file = new File(filePath) ;
file.eachLine {
println it
}
复制代码
能够看出Groovy的文件读取是很简洁的,还能够更简洁些:
def filePath = "D:/Android/name.txt"
def file = new File(filePath) ;
println file.text
复制代码
文件写入一样十分简洁:
def filePath = "D:/Android/name.txt"
def file = new File(filePath);
file.withPrintWriter {
it.println("三井寿")
it.println("仙道彰")
}
复制代码
asType能够用于数据类型转换:
String a = '23'
int b = a as int
def c = a.asType(Integer)
assert c instanceof java.lang.Integer
复制代码
if (name != null && name.length > 0) {}
复制代码
能够替换为
if (name) {}
复制代码
在Java中,要安全获取某个对象的值可能须要大量的if语句来判空:
if (school != null) {
if (school.getStudent() != null) {
if (school.getStudent().getName() != null) {
System.out.println(school.getStudent().getName());
}
}
}
复制代码
Groovy中可使用?.
来安全的取值:
println school?.student?.name
复制代码
对同一个对象的属性进行赋值时,能够这么作:
task method <<{
Person p = new Person()
p.name = "杨影枫"
p.age = 19
p.sex = "男"
println p.name
}
class Person {
String name
Integer age
String sex
}
复制代码
使用with来进行简化:
Person p = new Person()
p.with {
name = "杨影枫"
age= 19
sex= "男"
}
println p.name
复制代码
本文大概的介绍了Groovy的一些语法,包括:变量、方法、数据类型等等,比起Groovy 官方文档来讲,介绍的并很少,但不要忘了本系列的目标是学习与Android相关的Gradle,Groovy并非重点,咱们只须要了解本文所介绍的内容就够了,若是碰到哪里不会再去查找Groovy 官方文档和Groovy API文档。
感谢
www.groovy-lang.org/single-page… blog.csdn.net/u011054333/…
blog.csdn.net/yanical/art…
blog.csdn.net/zhaoyanjun6…
blog.csdn.net/singwhatiwa…
www.cnblogs.com/zqlxtt/p/57…
blog.csdn.net/u014099894/…
www.jianshu.com/p/ba55dc163…
不只分享大前端、Java、Android、跨平台等技术,还有大厂干货和程序员成长类文章。