上篇文章Gradle原理中讲到Gradle是一种依赖管理工具,基于Groovy语言,面向Java应用为主,它抛弃了基于XML的各种繁琐
配置,取而代之的是一种基于Groovy的领域特定(DSL)语言。
今天给大家讲一下Groovy语言是什么,它和java有哪些相同点和不同点。
1、Groovy语言是什么?
2、Groovy的特性
1、 构建在强大的Java语言之上 并 添加了从Python,Ruby和Smalltalk等语言中学到的 诸多特征,例如动态类型转换、闭包和元编程(metaprogramming)支持。。
2、为Java开发者提供了 现代最流行的编程语言特性,而且学习成本很低(几乎为零)。
3、 支持DSL(Domain Specific Languages领域定义语言)和其它简洁的语法,让代码变得易于阅读和维护。
4、受检查类型异常(Checked Exception)也可以不用捕获。
5、 Groovy拥有处理原生类型,面向对象以及一个Ant DSL,使得创建Shell Scripts变得非常简单。
6、在开发Web,GUI,数据库或控制台程序时 通过 减少框架性代码 大大提高了开发者的效率。
7、支持单元测试和模拟(对象),可以 简化测试。
8、无缝集成 所有已经存在的 Java对象和类库。
9、直接编译成Java字节码,这样可以在任何使用Java的地方 使用Groovy。[2]
10、支持函数式编程,不需要main函数。
11、一些新的运算符。
12、默认导入常用的包。
13、断言不支持jvm的-ea参数进行开关。
14、支持对对象进行布尔求值。
15、类不支持default作用域,且默认作用域为public。
16、groovy中基本类型也是对象,可以直接调用对象的方法。
3、Groovy的语法
许多 Java 开发人员喜欢 Groovy 代码和 Java 代码的相似性。从学习的角度看,如果知道如何编写 Java 代码,那就已经了解 Groovy 了。Groovy 和 Java 语言的主要区别是:完成同样的任务所需的 Groovy 代码比 Java 代码更少。
4、Groovy的类
Groovy类和java类一样,完全可以用标准java bean的语法定义一个Groovy类。但作为另一种语言,可以使用更Groovy的方式定义类,这样的好处是,可以少写一半以上的javabean代码。
(1)不需public修饰符
如前面所言,Groovy的默认访问修饰符就是public,如果Groovy类成员需要public修饰,则根本不用写它。
(2)不需要类型说明
同样前面也说过,Groovy也不关心变量和方法参数的具体类型。
(3)不需要getter/setter方法
在很多ide(如eclipse)早就可以为程序员自动产生getter/setter方法了,在Groovy中,不需要getter/setter方法--所有类成员(如果是默认的public)根本不用通过getter/setter方法引用它们(当然,如果一定要通过getter/setter方法访问成员属性,Groovy也提供了它们)。
(4)不需要构造函数
不再需要程序员声明任何构造函数,因为实际上只需要两个构造函数(1个不带参数的默认构造函数,1个只带一个map参数的构造函数--由于是map类型,通过这个参数可以构造对象时任意初始化它的成员变量)。
(5)不需要return
Groovy中,方法不需要return来返回值。
(6)不需要()
Groovy中方法调用可以省略()(构造函数除外)。
5、代码示例
5.1 定义变量
Groovy作为一门动态语言,所以肯定是支持动态类型。那么在定义变量的时候是可以不指定变量类型的。
5.2 类型
由于Groovy是基于Java的,所以Java常用类型都有。
String char byte short int long BigInteger
float double BigDecimal boolean List Map Array
5.3 String
5.4 List
5.5 Array数组
5.6 Map
5.7 函数
5.8 Closure闭包
5.9 执行闭包
6、Closure到底是个啥?
def langs = ['C++':'Stroustrup', Java:'Gosling', Lisp:'McCarthy']
def apply(Map<String,?> options){
options.each{
println it
}
}
apply langs
email {
from 'dsl-guru@mycompany.com'
to 'john.doe@waitaminute.com'
subject 'The pope has resigned!'
body {
p 'Really, the pope has resigned!'
}
}
实现这样的构建者往往要通过下面的方式:
def email(Closure cl) {
def email = new EmailSpec()
def code = cl.rehydrate(email, this, this)
code.resolveStrategy = Closure.DELEGATE_ONLY
code()
}
class EmailSpec {
void from(String from) { println "From: $from"}
void to(String... to) { println "To: $to"}
void subject(String subject) { println "Subject: $subject"}
void body(Closure body) {
def bodySpec = new BodySpec()
def code = body.rehydrate(bodySpec, this, this)
code.resolveStrategy = Closure.DELEGATE_ONLY
code()
}
}
代码中的一个问题在于,email 方法的用户并不知道他能在闭包内调用的方法。唯一的了解途径大概就是方法文档。
还有一个方式是,编译时解释委托策略@DelegatesTo。
def email(@DelegatesTo(EmailSpec) Closure cl) {
def email = new EmailSpec()
def code = cl.rehydrate(email, this, this)
code.resolveStrategy = Closure.DELEGATE_ONLY
code()
}
2.Gradle有自己的DSL和构建流程Gradle DSL。
3.Gradle插件Android Plugin有自己的DSL Android Plugin DSL。