前言

gradle是一个基于JVM的构建工具,它结合了Python、Ruby和Smalltalk的许多强大的特性,Groovy 代码能够与Java代码很好地结合,也能用于扩展现有代码。由于其运行在 JVM 上的特性,Groovy可以使用其他Java语言编写的库。目前已经应用在多数Android技术体系中,比如,jenkins,插件化,组件化,模块化等等。如果你不了解gradle,那么前面几个技术点很难深入理解。

Groovy 的语法跟 kotlin 类似,如果我们有 kotlin 的经验的话那么学习 groovy 会容易很多。下面我们一起来学习下groovy的核心语法,大家可以跟着样例敲一下加深理解、记忆。

基本特点

  • 构建在强大的Java语言之上 并 添加了从Python,Ruby和Smalltalk等语言中学到的 诸多特征,例如动态类型转换、闭包和元编程(metaprogramming)支持。
  • 为Java开发者提供了 现代最流行的编程语言特性,而且学习成本很低(几乎为零)。
  • 支持DSL(Domain Specific Languages领域定义语言)和其它简洁的语法,让代码变得易于阅读和维护。
  • 受检查类型异常(Checked Exception)也可以不用捕获。
  • Groovy拥有处理原生类型,面向对象以及一个Ant DSL,使得创建Shell Scripts变得非常简单。
  • 在开发Web,GUI,数据库或控制台程序时 通过 减少框架性代码 大大提高了开发者的效率。
  • 支持单元测试和模拟(对象),可以 简化测试。
  • 无缝集成 所有已经存在的 Java对象和类库。
  • 直接编译成Java字节码,这样可以在任何使用Java的地方 使用Groovy。
  • 支持函数式编程,不需要main函数。
  • 一些新的运算符。
  • 默认导入常用的包。
  • 断言不支持jvm的-ea参数进行开关。
  • 支持对对象进行布尔求值。
  • 类不支持default作用域,且默认作用域为public。
  • groovy中基本类型也是对象,可以直接调用对象的方法。

基础语法

Groovy中的变量

groovy中变量既可以像java一样是强类型的,也可以像kotlin一样是弱类型的。
代码示例如下:

1
2
3
4
5
6
7
8
class Study {
static void main(String[] args) {
String a = 'Hello World'
def b = "Hello Silence"
println(a)
println(b)
}
}

输出结果如下:

1
2
Hello World
Hello Silence

Groovy中的运算符和条件控制

与java一致,这里不过多介绍

Groovy中的字符串

Groovy提供了多种表示String字面量的方法。Groovy中的字符串可以用单引号(’),双引号(“)或三引号(“““)括起来。此外,由三重引号括起来的Groovy字符串可以跨越多行。

示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
class Study {
static void main(String[] args) {
String a = 'Hello World'
def b = "Hello Silence"
def c = '''Hello World
Hello Silence'''
println(a)
println(b)
println(c)
}
}

运行结果如下:

1
2
3
4
Hello World
Hello Silence
Hello World
Hello Silence
字符串的扩展

Groovy的扩展和kotlin的一样,示例代码如下:

1
2
3
4
5
6
7
8
class Study {
static void main(String[] args) {
String a = 'Hello World'
def b = "Hello $a"
println(a)
println(b)
}
}

输出结果如下:

1
2
Hello World
Hello Hello World
字符串的索引

Groovy中的字符串是字符的有序序列。字符串中的单个字符可以通过其位置访问。这由索引位置给出。

字符串索引从零开始,以小于字符串长度的一个结束。Groovy还允许负索引从字符串的末尾开始计数。

具体示例代码如下:

1
2
3
4
5
6
7
8
9
class Study {
static void main(String[] args) {
String a = 'Hello World'
println(a[1])//输出坐标为1的内容
println(a[-2])//输出坐标为倒数第二的内容
println(a[1..2])//输出坐标区间为1-2的内容
println(a[2..5])//输出坐标区间为2-5的内容
}
}

输出结果如下:

1
2
3
4
e
l
el
llo

数据结构

Range范围

范围是指定值序列的速记。范围由序列中的第一个和最后一个值表示,Range可以是包含或排除。包含范围包括从第一个到最后一个的所有值,而独占范围包括除最后一个之外的所有值。

  • 1..10 — 包含范围的示例
  • 1 .. <10 - 独占范围的示例
  • ‘a’..’x’ - 范围也可以由字符组成
  • 10..1 - 范围也可以按降序排列
  • ‘x’..’a’ - 范围也可以由字符组成并按降序排列。
方法 描述
contains() 检查范围是否包含特定值
get() 返回此范围中指定位置处的元素。
getFrom() 获得此范围的下限值。
getTo() 获得此范围的上限值。
isReverse() 这是一个反向的范围,反向迭代
size() 获得范围的元素值。
subList() 返回此指定的fromIndex(包括)和toIndex(排除)之间的此范围部分的视图。

List

列表是用于存储数据项集合的结构。在 Groovy中,List保存了一系列对象引用。

List中的对象引用占据序列中的位置,并通过整数索引来区分。

groovy 中的一个列表中的数据可以是任意类型。这和java下集合列表有些不同,java下的列表是同种类型的数据集合。

groovy中列表还可以嵌套列表。如[1,2,[3,4,5],“aaa”]groovy列表内置有反转方法 reverse()。调用 List.reverse() 可以实现列表反转。groovy列表内置有排序方法 sort()。调用 List.sort() 可以实现列表排序。空列表表示为[]声明一个空集合。

Map

Map是对象引用的无序集合。Map集合中的元素由键值访问。Map中使用的键可以是任何类。当我们插入到Map集合中时,需要两个值:键和值。

面向对象

三大特性

Groovy中的面向对象和其他任何的面向对象语言一样,存在类和对象的概念。不过在groovy新增了一个trait的关键字,名为特征。

Groovy中的特征

特征是语言结构的构造,其他包括:

  • 行为的组成
  • 接口运行时的实现
  • 与静态类型检查/编译的兼容性

使用trait关键字定义特征。示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Study {
static void main(String[] args) {
Student st = new Student();
st.StudentID = 1
st.Marks1 = 10
st.DisplayMarks()
}
}

trait Marks {
void DisplayMarks() {
println("Display Marks")
}
}

class Student implements Marks {
int StudentID
int Marks1
}

输出结果如下:

1
Display Marks

上述示例中trait是类似接口的存在,同理,trait也可以实现接口。
示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Study {
static void main(String[] args) {
Student st = new Student();
st.StudentID = 1
st.Marks1 = 10
st.DisplayMarks()
st.DisplayTotal()
}
}

interface Total {
void DisplayTotal()
}

trait Marks implements Total {
void DisplayMarks() {
println("Display Marks")
}

void DisplayTotal() {
println("Display Total")
}
}

class Student implements Marks {
int StudentID
int Marks1
}

输出结果如下:

1
2
Display Marks
Display Total

扩展特征

特征的扩展则使用extends关键字,示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
trait Marks {
void DisplayMarks() {
println("Marks1");
}
}

trait Total extends Marks {
void DisplayMarks() {
println("Total");
}
}

Groovy中的闭包

闭包是一个短的匿名代码块,个人理解是和lamda是差不多的。
下面是一个简单的闭包例子,代码如下:

1
2
3
4
5
6
class Study {
static void main(String[] args) {
def test = { println "Hello World" }
test.call()
}
}

输出结果如下:

1
Hello World

闭包中的形式参数

闭包也可以包含形式参数,以使它们更有用,就像Groovy中的方法一样。

1
2
3
4
5
6
7
class Study {
static void main(String[] args) {
def hello="Hello"
def test = {params -> println "$hello World" }
test.call()
}
}

输出结果也是Hello World。
当然我们还有另外一种写法:

1
2
3
4
5
6
class Study {
static void main(String[] args) {
def test = { println "Hello ${it}" }
test.call("World")
}
}

我们还可以把上面两种的形式,进行组合,示例代码如下:

1
2
3
4
5
6
7
class Study {
static void main(String[] args) {
def hello="Hello"
def test = { params ->println "$hello ${params}" }
test.call("World")
}
}

在方法中使用闭包

类似kotlin的方法中可以传匿名函数一样。示例代码如下:

1
2
3
4
5
6
7
8
9
10
11
class Study {
static void main(String[] args) {
def hello="Hello"
def test = { params ->println "$hello ${params}" }
Study.Display(test)
}

def static Display(clo) {
clo.call("Silence")
}
}

输出结果如下:

1
Hello Silence

Groovy中的Json

我们先来看看 groovy 中对象与 json 字符串之间的相互转换:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import groovy.json.JsonOutput

class Study{
public static void main(String[] args) {
def study = [new Person("silence", 25),
new Person("david", 26)]
def json=JsonOutput.toJson(study)
println json
//带格式的输出json
println JsonOutput.prettyPrint(json)
}
}


class Person {
private String name
private int age

Person(String name, int age) {
this.name = name
this.age = age
}

String getName() {
return name
}

void setName(String name) {
this.name = name
}

int getAge() {
return age
}

void setAge(int age) {
this.age = age
}
}

输出结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
[{"age":25,"name":"silence"},{"age":26,"name":"david"}]
[
{
"age": 25,
"name": "silence"
},
{
"age": 26,
"name": "david"
}
]

总结

本篇主要讲解了groovy的基本语法,整体上是和kotlin和java的语法是差不多的。相对而言,熟悉kotlin和java的,上手groovy会很快。

参考

暴力突破 Gradle 自动化项目构建(二)- Groovy 核心语法
Groovy教程