Groovy语言

       上篇文章Gradle原理中讲到Gradle是一种依赖管理工具,基于Groovy语言,面向Java应用为主,它抛弃了基于XML的各种繁琐

配置,取而代之的是一种基于Groovy的领域特定(DSL)语言。

今天给大家讲一下Groovy语言是什么,它和java有哪些相同点和不同点。

1、Groovy语言是什么?

Groovy 是 用于Java虚拟机的一种敏捷的动态语言,它是一种成熟的面向对象编程语言,既可以用于面向对象编程,又可以用作纯粹的脚本语言。使用该种语言不必编写过多的代码,同时又具有闭包和动态语言中的其他特性。
Groovy是JVM的一个替代语言(替代是指可以用 Groovy 在Java平台上进行 Java 编程),使用方式基本与使用 Java代码的方式相同,该语言特别适合与Spring的动态语言支持一起使用,设计时充分考虑了Java集成,这使 Groovy 与 Java 代码的互操作很容易。(注意:不是指Groovy替代java,而是指Groovy和java很好的结合编程。

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的语法
Groovy 语法与Java 语言的语法很相似,虽然 Groovy 的语法源于Smalltalk和Ruby这类语言的理念,但是可以将它想像成 Java 语言的一种更加简单、表达能力更强的变体。(在这点上,Ruby与 Groovy 不同,因为它的语法与 Java 语法差异很大。)
许多 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
Groovy中的List使用的是java.util.List,默认使用ArrayList,如果你想要使用LinkedList需要特别指明;List是动态的,里面可以同时放不同类型的数据。
5.5 Array数组
在Groovy中,使用Array数组和使用List最大的区别就是,Array数组必须指定类型。
5.6 Map
5.7 函数
Groovy中的函数可以不指定返回值类型,可以不指定参数类型,函数代码中的最后一行表达式就是返回值,调用函数的时候可以省略圆括号。例如:
   
 5.8 Closure闭包
   定义一个闭包的语法如下:
[closureParameters -> ] 部分能够接受参数,可以省略,参数可以是动态无类型的,也可以是指定类型的,但是如果指定类型了就必须按照类型传参。
     
5.9 执行闭包
我们可以像执行函数一样去执行一个闭包,也可以调用闭包的call方法来执行闭包,看例子:
   
   有一个地方注意一下,{ println it } 是默认有一个参数的,但是 { -> println it } 这么写在执行的时候是会报错的,因为你显示声明了这个Closure没有参数。

6、Closure到底是个啥?

Closure是一个groovy.lang.Closure对象,这就解释了为什么他可以赋值给一个变量,也就是说,我们可以用这个来写函数式编程了。

可以看出,each方法接受一个类型是Closure类型的参数,然后执行这个参数。

def langs = ['C++':'Stroustrup', Java:'Gosling', Lisp:'McCarthy']  

def apply(Map<String,?> options){
    options.each{
        println it
    }
}

apply langs

Groovy的建构者模式(Groovy实现建构的方式)
email {
    from 'dsl-guru@mycompany.com'
    to 'john.doe@waitaminute.com'
    subject 'The pope has resigned!'
    body {
        p 'Really, the pope has resigned!'
    }
}



使用构建者策略可实现,利用一个参数为闭包的名为 email 的方法,它会将随后的调用委托给一个对象,该对象实现了 from、to、subject 及 body 各方法。body 方法使用闭包做参数,使用的是构建者策略。
实现这样的构建者往往要通过下面的方式:

def email(Closure cl) {
    def email = new EmailSpec()
    def code = cl.rehydrate(email, this, this)
    code.resolveStrategy = Closure.DELEGATE_ONLY
    code()
}



EmailSpec 类实现了 from、to 等方法,通过调用 rehydrate,创建了一个闭包副本,用于为该副本设置 delegate、owner 及 thisObject 等值。设置 owner 和 thisObject 并不十分重要,因为将使用 DELEGATE_ONLY 策略,解决方法调用只针对的是闭包委托。

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()
    }
}

The EmailSpec 类自身的 body 方法将接受一个复制并执行的闭包,这就是Groovy 构建者模式的原理。
代码中的一个问题在于,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()
}

大致的作用就是通过这个@DelegatesTo 让编译器知道这和Closure代理给谁,可以更智能显示填写哪些参数,这里这不阐述了,后续文章我会在重点讲一下闭包的用法。


传送门
1.Groovy语言相关内容请查阅Groovy官网
2.Gradle有自己的DSL和构建流程Gradle DSL
3.Gradle插件Android Plugin有自己的DSL Android Plugin DSL

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值