1
头图

初探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动态执行

image-20220909084411141.png

毕竟是动态语言,出于性能考虑,建议核心代码、底层代码,用Java。业务逻辑、需要快速变化的逻辑,尝试用Groovy。

IDE支持

由于是动态语言,IDE支持极为重要。目前IDEA支持良好,groovy插件已加入默认配置。

image-20220909084507221.png

如何构建?

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

参考文献


骚铭科技
1 声望2 粉丝

条路自己行,扑街唔好喊