Groovy 语言快速入门

前言

由于项目需要用到 Groovy 语言,这两天对其进行了粗略的学习,本文是对学习做的一个简单总结,主要内容参考于官方文档(Groovy 的官方文档还是非常不错的,强烈推荐阅读),希望本文对准备学习使用或者对 Groovy 感兴趣的同学有所帮助,如有不对之处还望指出哈,对这门语言的理解还是比较肤浅的。

简介

Groovy 是 Apache 旗下的一门基于 JVM 平台的动态/敏捷编程语言,在语言的设计上它吸纳了 Python、Ruby 和 Smalltalk 语言的优秀特性,语法非常简练和优美,开发效率也非常高(编程语言的开发效率和性能是相互矛盾的,越高级的编程语言性能越差,因为意味着更多底层的封装,不过开发效率会更高,需结合使用场景做取舍)。并且,Groovy 可以与 Java 语言无缝对接,在写 Groovy 的时候如果忘记了语法可以直接按Java的语法继续写,也可以在 Java 中调用 Groovy 脚本,都可以很好的工作,这有效的降低了 Java 开发者学习 Groovy 的成本。Groovy 也并不会替代 Java,而是相辅相成、互补的关系,具体使用哪门语言这取决于要解决的问题和使用的场景。

快速开始

1.下载Groovy开发工具包(GDK)

http://www.groovy-lang.org/download.html

2.创建Groovy项目

使用IDEA的话需要安装Groovy的支持插件,安装完成后在新建项目中便会出现Groovy项目选项,选择Groovy项目并关联Groovy libray即可,当然也可以直接创建.groovy文件用命令行直接运行。

3.Hello World

在Java中要输出“hello world”需要像下面这样,创建一个类,然后创建一个main方法。

Groovy 语言快速入门

在Groovy中,这些都可以省略,下面这4种方式都可以输出“hello world”。

Groovy 语言快速入门

当然,也可以像Java一样运行在类的main方法中。

Groovy 语言快速入门

如果 Groovy 脚本文件里只有执行代码,没有类的定义,则 Groovy 编译器会生成一个 Script 的子类,类名和脚本文件的文件名一样,而脚本中的代码会被包含在一个名为run的方法中,同时还会生成一个main方法,作为整个脚本的入口。所以,作为 JVM 平台语言,与 Java 本质上还是一样的。

与Java的一些区别

默认导入

Groovy 会默认导入下面这些包、类,不需要使用import语句显式导入。

Groovy 语言快速入门

多重方法

在 Groovy 中,调用的方法将在运行时被选择。这种机制被称为运行时分派或多重方法(multi-methods),是根据运行时实参(argument)的类型来选择方法。Java 采用的是相反的策略:编译时根据声明的类型来选择方法。

下面是一个例子,同样的 Java 代码在 Java 和 Groovy 环境中运行结果是不同的.

Groovy 语言快速入门

产生差异的原因在于,Java 使用静态数据类型,o 被声明为 Object 对象,而 Groovy 会在运行时实际调用方法时进行选择。因为调用的是 String 类型的对象,所以自然调用 String 版本的方法。

数组初始化语法

在 Groovy 中,{…} 语句块是留给闭包(Closure)使用的,所以不能像 Java 中一样使用下面这种方式初始化数组

int[] array = { 1, 2, 3}

而应该是下面这样

int[] array = [1,2,3]

POJO

Groovy 默认会隐式的创建getter、setter方法,并且会提供带参的构造器,下面两者是等价的。

Groovy 语言快速入门

包访问权限

在 Java 中如果没有显式的指定访问修饰符(public、protected、private)那么默认是包访问权限,但在 Groovy 中默认是public的,所以需要使用@PackageScope注解。

class Person {
@PackageScope String name
}

ARM 语句块

ARM(Automatic Resource Management,自动资源管理)语句块(或者叫TWR语法)从 Java 7 开始引入,用于降低IO操作代码的复杂度,但 Groovy 并不支持。相反,Groovy 提供多种基于闭包的方法,不但可以达到同样的效果并且会更加简洁优美。

Groovy 语言快速入门

内部类

Groovy 同样支持内部类并且实现跟 Java 是一样的,但不应拿 Java 语言规范来考量它,应对差异情况保持冷静与宽容(keep shaking the head about things that are different)。在Groovy中内部类看起来有点类似 groovy.lang.Closure 类的实现。

Groovy 语言快速入门

Lambda 表达式

Java 8 支持 Lambda 表达式和方法引用

Runnable run = () -> System.out.println("Run");
list.forEach(System.out::println);

Java 8 的 lambda 几乎可以认为是匿名内部类。Groovy 并没有采用这种语法,而采用闭包来实现。

Runnable run = { println 'run' }
list.each { println it } // or list.each(this.&println)

GString

由于双引号所包括起来的字符串字面量会被解释为 GString 值(即 “Groovy 字符串”的简称),所以如果当某个类中的 String 字面量含有美元字符($)时,那么利用 Groovy 和 Java 编译器进行编译时,Groovy 很可能就会编译失败,或者产生与 Java 编译所不同的结果。

通常,如果某个 API 声明了形参的类型,Groovy 会自动转换 GString 和 String。要小心那些形参为 Object 的 Java API,需要检查它们的实际类型。

字符串和字符字面量

在 Groovy 中,由单引号所创建的字面量属于 String 类型对象,而双引号创建的字面量则可能是 String 或 GString 对象,具体分类由字面量中是否有插值来决定。

assert 'c'.getClass()==String
assert "c".getClass()==String
assert "c${1}".getClass() in GString

基础语法

  • Groovy 语句无需使用分号(;)结尾,当然加上也不会报错,毕竟完全兼容 Java 的语法。

  • Groovy 中==等价于 Java 中的equals方法。

注释

注释和 Java 一样,支持单行(//)、多行(/* */)和文档注释(/** */)

除此之外还支持 Shebang line(UNIX系统支持一种特殊的单行注释叫作 Shebang line,用于指明脚本的运行环境,便于在终端中可以直接运行)#号必须是文件的第一个字符。

#!/usr/bin/env groovy
println "Hello from the shebang line"

变量

Groovy 中定义变量默认访问修饰符是public,变量定义时遵循 Java 变量命名规范,变量名以字母、下划线或美元符号$开始,可以包含字母、数字、下划线和美元符号$,但关键字除外。除了这些规则之外,Groovy 定义变量时如果是一行定义一个类型,末尾的分号可以省略,但是如果多个变量占一行,变量之间必须以分号分割。

Groovy 定义变量的方式和 Java 是类似的,区别在于 Groovy 提供了def关键字供使用,它可以省略变量类型的定义,根据变量的值进行类型推导。

Groovy 语言快速入门

如果定义变量的字面量值为数字时,类型会根据数字的大小自动调整

Groovy 语言快速入门

对于浮点型字面量为了精度 Groovy 默认使用的类型为 BigDecimal

def decimal = 123.456
println decimal.getClass() // class java.math.BigDecimal

Groovy为 数字类型提供一种更简单的声明类型的方式:类型后缀

Groovy 语言快速入门

Groovy 语言快速入门

使用例子

def a = 123I
assert a instanceof Integer
def b= 123L
assert b instanceof Long

字符串

在Groovy种有两种字符串类型,普通字符串(java.lang.String)和插值字符串(groovy.lang.GString)。

普通字符串使用单引号

println 'hello'

插值字符串使用双引号

def name = '张三'
println "hello $name"

除此之外,还支持三单引号的写法,可以保留文本的换行及缩进格式

Groovy 语言快速入门

字符

在 Groovy 中并没有明确的字符字面量表示形式,需要显示的指定,有三种方式

Groovy 语言快速入门

方法(函数)

Groovy 方法的默认访问修饰符是public,方法的返回类型可以不需要声明,但需添加def关键字。有返回值的方法return可以被省略,默认返回最后一行代码的运行结果,如果使用了return关键字则返回指定的返回值。

Groovy 语言快速入门

Groovy 方法的参数类型可以被省略,默认为Object类型。

Groovy 语言快速入门

Groovy 方法的其他特性与Java一样,比如支持重载、不定长参数(…)等。

闭包

Groovy 提供了闭包的支持,语法和 Lambda 表达式有些类似,简单来说就是一段可执行的代码块或函数指针。闭包在 Groovy 中是groovy.lang.Closure类的实例,这使得闭包可以赋值给变量,或者作为参数传递。Groovy 定义闭包的语法很简单,就像下面这样。

//闭包的参数为可选项
def closure = { [closureParameters -> ] statements }

闭包可以访问外部变量,而方法(函数)则不能。

def str = 'hello'
def closure={
println str
}
closure()//hello

闭包调用的方式有两种,闭包.call(参数)或者闭包(参数),在调用的时候可以省略圆括号。

def closure = {
param -> println param
}

closure('hello')
closure.call('hello')
closure 'hello'

闭包的参数是可选的,如果没有参数的话可以省略->操作符。

def closure = {println 'hello'}
closure()

多个参数以逗号分隔,参数类型和方法一样可以显式声明也可省略。

def closure = { String x, int y -> 
println "hey ${x} the value is ${y}"
}

如果只有一个参数的话,也可省略参数的定义,Groovy提供了一个隐式的参数it来替代它。

def closure = { it -> println it } 
//和上面是等价的
def closure = { println it }
closure('hello')

闭包可以作为参数传入,闭包作为方法的唯一参数或最后一个参数时可省略括号。

def eachLine(lines, closure) {
for (String line : lines) {
closure(line)
}
}
eachLine('a'..'z',{ println it })
//可省略括号,与上面等价
eachLine('a'..'z') { println it }

Lists

Groovy 定义 List 的方式非常简洁,使用中括号([]),以逗号(,)分隔元素即可。Groovy中的 List 其实就是java.util.List,实现类默认使用的是java.util.ArrayList。

def numbers = [1, 2, 3] 
assert numbers instanceof List
assert numbers.class == java.util.ArrayList
assert numbers.size() == 3

Arrays

Groovy 定义数组的语法和 List 非常类似,区别在于数组的定义必须指定类型为数组类型,可以直接定义类型或者使用def定义然后通过as关键字来指定其类型。

String[] arrStr = ['Ananas', 'Banana', 'Kiwi'] //直接声明类型为数组类型 String[]
assert arrStr instanceof String[]
assert !(arrStr instanceof List)
def numArr = [1, 2, 3] as int[] //痛过as关键字指定类型为数组类型 int[]
assert numArr instanceof int[]
assert numArr.size() == 3

Maps

Groovy 定义 Map 的方式非常简洁,通过中括号包含key、val的形式,key和value以冒号分隔([key:value])。Groovy中的Map其实就是java.util.Map,实现类默认使用的是java.util.LinkedHashMap。

Groovy 语言快速入门

Range

在 Groovy 中可以使用..操作符来定义一个区间对象,简化范围操作的代码。

Groovy 语言快速入门

常见使用场景

Grails

Grails 是一个基于 Groovy 语言,构建于 Spring/Spring Boot、Hibernate 之上的高生产力、一站式 Web 开发框架。特别适合小型团队进行敏捷开发,效率非常高。由于性能和学习成本的原因,普及率比较低,大分部公司还是更倾向于选择 Spring Boot 作为开发框架。

Gradle

Gradle 是一个基于 Apache Ant 和 Apache Maven 概念的项目自动化构建工具。它使用一种基于 Groovy 的特定领域语言(DSL)来进行构建配置,抛弃了基于XML的各种繁琐配置,主要以面向Java应用为主,支持从 Maven 仓库下载依赖。现在越来越多的项目(Android项目居多)使用Gradle 来作为项目的构建工具,相信未来 Gradle 也会逐渐代替 Maven,就像 Maven 代替 Ant 那样。

使用Maven构建项目

Groovy 语言快速入门

Groovy 语言快速入门

使用Gradle构建项目

Groovy 语言快速入门

Spring 支持

从 Spring 2.0 版本开始对动态脚本语言进行了支持(Spring 官方文档该部分地址),其中便包括 Groovy ,Spring 提供了<lang:groovy/>标签来定义 Groovy Bean 。Groovy Bean 可以通过script-source属性加载脚本文件,脚本源文件可以来自本地或者网络,并且可以通过refresh-check-delay属性监听脚本内代码变更重新装载 Bean 实现动态 Bean 。

Groovy 语言快速入门

从 Spring 4.0 版本开始 Spring 支持使用 Groovy DSL 来定义 Bean 的配置,详见 Spring 官方文档该部分 。

Groovy 语言快速入门

与Java集成

Groovy非常容易集成在Java环境中,利用其动态性来做规则引擎、流程引擎、动态脚本环境,非常适合那些不不需要经常发布但又经常变更的场景下使用。在Java中集成(调用)Groovy 代码有下面几种方式。

Eval

groovy.util.Eval 类是最简单的用来在运行时动态执行 Groovy 代码的类,提供了几个静态工厂方法供使用,内部其实就是对GroovyShell的封装。

Groovy 语言快速入门

GroovyShell

groovy.lang.GroovyShell除了可以执行 Groovy 代码外,提供了更丰富的功能,比如可以绑定更多的变量,从文件系统、网络加载代码等。

Groovy 语言快速入门

GroovyClassLoader

groovy.lang.GroovyClassLoader是一个定制的类加载器,可以在运行时加载 Groovy 代码,生成 Class 对象。

Groovy 语言快速入门

GroovyScriptEngine

groovy.util.GroovyScriptEngine能够处理任何 Groovy 代码的动态编译与加载,可以从统一的位置加载脚本,并且能够监听脚本的变化,当脚本发生变化时会重新加载。

Groovy 语言快速入门

JSR 223 javax.script API

JSR-223 是 Java 中调用脚本语言的标准 API。从 Java 6 开始引入进来,主要目的是用来提供一种统一的框架,以便在 Java 中调用多种脚本语言。JSR-223 支持大部分流行的脚本语言,比如JavaScript、Scala、JRuby、Jython和Groovy等。

Groovy 语言快速入门

由于 Groovy 自身已经提供了更丰富的集成机制,如果在 Java 应用中只是使用 Groovy 一种脚本语言的话,使用 Groovy 提供的集成机制可能会更合适一点。

来源:悦码,本文观点不代表自营销立场,网址:https://www.zyxiao.com/p/94317

发表评论

电子邮件地址不会被公开。 必填项已用*标注

侵权联系
分享本页
返回顶部