初探Groovy
简介
Groovy 是一门 JVM 语言,因此只要有JVM即可执行。而且Groovy与Java可以相互调用,亲测丝滑。
丝滑到什么程度呢?就是在Java项目项目中可以同时并存.java
和.groovy
文件,可以相互调用。
Groovy 是动态语言,引入很多有意思的特性。如果将Java比喻为楷书,则Groovy是行书,开发效率很高。而且Groovy JDK中包含很多实用工具,开发舒适。
目标
Groovy is an optionally typed, dynamic language for the Java platform with many features that are inspired by languages like Python, Ruby, and Smalltalk, making them available to Java developers using a Java-like syntax. Unlike other alternative languages, it is designed as a companion, not a replacement for Java.
—— Groovy In Action (page 44)
我们的目标不是要替换Java,而是成为Java的伙伴。将一些用Java处理起来很复杂的工序,交给Groovy处理。
运行方式
简单而言有两种方式:
- compile:编译期编译为
.class
文件 - runtime:作为脚本由
GroovyShell
动态执行
毕竟是动态语言,出于性能考虑,建议核心代码、底层代码,用Java。业务逻辑、需要快速变化的逻辑,尝试用Groovy。
IDE支持
由于是动态语言,IDE支持极为重要。目前IDEA支持良好,groovy插件已加入默认配置。
如何构建?
Build | 配置文件 | 配置 | 评估 |
---|---|---|---|
Gradle | .groovy | 简洁 | 最佳构建方式,但没人用过 |
Maven | .XML | 复杂 | 虽然复杂,但大家都在用,熟悉,建议用maven引入 |
Ant | \ | \ | 淘汰了,不讨论 |
maven groovy 有多种插件,建议使用 GMavenPlus。
具体配置方法参考:Groovy + Java 混合编程方案:GMaven - SegmentFault 思否
究竟有多爽?
POGO
在Java项目中,纯数据类我们称之为POJO。POJO往往要加一堆构造方法和getter、setter,虽然可以利用IDE生成或者lombok,但是看着还是很啰嗦。
在Groovy可以构造POGO,
class Person {
String id
String name
String toString() {
return "$id,$name"
}
}
默认构造、Map构造、getter、setter都是默认的,非常简洁。
def person = new Person(id: '67', name: '靓仔')
println person.getName()
除此之外,还可以将POGO搞成不可以变类型,连final
都省了,
@Immutable
class ImmutablePoint {
double x
double y
String toString() {
return "($x,$y)"
}
}
关于POGO还有一些实用功能,可以参考Making Java Groovy 的第四章。
GString
类似于Python的 f-string 和 JS 的模板字符串。GString中使用dollar符作为变量占位符。下面是 Groovy In Action 文中的例子(page 84):
def me = 'Tarzan'
def you = 'Jane'
def line = "me $me - you $you"
assert line == 'me Tarzan - you Jane'
def date = new Date(0)
def out = "Year $date.year Month $date.month Day $date.date"
assert out == 'Year 70 Month 0 Day 1'
out = "Date is ${date.toGMTString()} !" //|#3 Full syntax with
assert out == 'Date is 1 Jan 1970 00:00:00 GMT !' //|#3 curly braces
//多行 GStrings
def sql = """
SELECT FROM MyTable
WHERE Year = $date.year
"""
assert sql == """
SELECT FROM MyTable
WHERE Year = 70
"""
out = "my 0.02$" //|#5 Literal dollar sign
assert out == 'my 0.02$'
json
import groovy.json.JsonSlurper
String url = 'http://api.icndb.com/jokes/random?limitTo=[nerdy]'
String jsonTxt = url.toURL().text
def json = new JsonSlurper().parseText(jsonTxt)
def joke = json?.value?.joke
println joke
接口调用,json解析一气呵成。而且取值过程非常简洁:json?.value?.joke
,再也不需要一堆if else 判断了,也不需要诸如Optional
的方法取值。
单元测试
Groovy makes testing Java much easier
—— Making Java Groovy
如果想使用Groovy,但是又对应用于业务逻辑心存疑虑,那么用来写单元测试是再合适不过了。不会影响业务代码,又可以逐步上手,单元测试写起来又简洁。
class CutoutCustomerIdTagTest {
@Test
void cutout() {
def ctx = new DmContext(uid: '001122')
def cutId = new CutoutCustomIdTag().doTag(ctx)
assert cutId == '22'
}
}
class PermissionTest {
@Test
void check() {
def permission = new Permission(modify: ['Tom', 'Jerry'])
assert permission.checkModify('Tom')
assert permission.checkModify('Jerry')
}
}
参考文献
- Groovy In Action 2ed
- Making Java Groovy
- Groovy官网