Groovy 使用笔记
大约 4 分钟
Groovy 是可在 JVM 中运行的脚本语言。 同时, Groovy 有面向对象的特性。
相关信息
其他可在 JVM 中运行的脚本语言有: Groovy, JRuby, JPython, BeanShell, JavaScript, ...
Groovy 在 JSR241 中被 Java 引入,在 2007 年 1 月发布第一个版本。
安装
- 下载 bin
- 配置环境变量
> scoop install groovy
> groovy -v
Groovy Version: 4.0.22 JVM: 11.0.20 Vendor: Oracle Corporation OS: Windows 11
相关信息
Groovy 自带命令行编辑器,在 ${GROOVY_HOME}/bin
下。
linux
groovyConsole
windows
groovyConsole.bat
目录
bin/groovy.bat # 执行 groovy
bin/groovyc.bat # 编译 todo
bin/groovysh.bat # 执行 todo
doc/ # todo
GDK
GDK(Groovy JDK) 扩展了 JDK。
如调用系统命令的方式:
JDK
try {
Process process = Runtime.getRuntime().exec("git help");
BufferReader result = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while((line = result.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
GDK
println "git help".execute().text
语法
变量:字符串
// 定义变量 - 字符串
def str = 'hello world' // 纯字符串
def str = '''hello
world''' // 允许多行
def str = "Hello ${str}" // 允许插值
def str = """Hello
${str}
World!""" // 允许多行 + 允许插值
// 定义变量 - 正则
def regex = /hello/
变量:数值
// 定义变量 - 数值
def // 自动类型识别
// def
def b = Integer.MAX_VALUE // 2147483647
assert b instanceof Integer
def c = b + 1 // -2147483648
// def c = 2147483647 + 1 // -2147483648
assert c instanceof Integer
def l = 2147483647 // Integer.MAX_VALUE + 1
assert l instanceof Long
// 二进制 0b
assert 0b1000 == 8
// 八进制 0
assert 077 == 63
// 十六进制
assert 0x77 == 119
// 科学计数法
assert 1e3 == 1_000.0 // 1 x 10^3 // Groovy 支持 _ 下划线对数字进行分割,使得数值易于识别
assert 2E4 == 20_000.0 // 2 x 10^4
assert 3e+1 == 30.0
assert 4E-2 == 0.04
assert 5e-1 == 0.5
// 显式指定类型
byte
char
short
int
long
java.math.BigInteger // 计算精度
int a = 1
// 通过后缀指定类型
G/g BigDecimal
G/g BigInteger
L/l Long
I/i Integer
D/d Double
F/f Float
def a = 42I
变量:集合
// 定义
def numbers = [1, 2, 3]
assert numbers instanceof List // 默认使用 java.util.ArrayList
assert numbers.size() == 3
def heterogeneous = [1, "a", true] // 可放入不同类型元素
def linkedList = [2, 3, 4] as LinkedList // 显式指定类型
LinkedList otherLinked = [3, 4, 5]
assert linkedList instanceof java.util.LinkedList
def numArr = [1, 2, 3] as int[] // 显式指定为数组
String[] arrStr = ["Ananas", "Banana", "Kiwi"]
assert arrStr instanceof String[]
assert !(arrStr instanceof List)
// 访问
def letters = ['a', 'b', 'c', 'd']
assert letters[0] == 'a'
// 遍历
String[] groovyBooks = ['Groovy in Action', 'Making Java Groovy']
assert groovyBooks.every{ it.contains('Groovy') }
// 添加
letters << 'e' // 末尾添加
assert letters[ 4] == 'e'
assert letters[-1] == 'e'
变量:Map
相关信息
Groovy 的 map 对象就是 LinkedHashMap 实例
def colors = [red: '#FF0000', green: '#00FF00', blue: '#0000FF']
assert colors['red'] == '#FF0000'
assert colors.green == '#00FF00'
colors['pink'] = '#FF00FF'
colors.yellow = '#FFFF00'
定义:方法
// 定义方法
def 'abstract'() { true }
todo
todo https://www.bilibili.com/video/BV1214y1r76z
todo 关系运算、逻辑运算、位运算、对象运算、正则
todo 类、内部类、继承(extend)、抽象类(abstract)、接口(interface/implements)
todo trait
定义:类
class Person {
String name
Integer age
}
Person.metaClass.sex = "女" // 动态添加 sex 属性
Person.metaClass.setNameUpperCase = {->name.toUpperCase()} // 动态添加方法
Person.metaClass.static.setNameLowerCase = {String name -> name.toLowerCase()} // 动态添加静态方法
def p = new Person(name:"xx",age:19)
println p.sex
println p.setNameUpperCase()
println Person.setNameLowerCase("ABC")
定义:闭包(Closure)
def pickEven(n, block) {
for(int i=2; i<=n; i+=2) {
block(i); // 指向闭包的调用
}
}
pickEven(10, {println it}); // {} 匿名代码块
变量
this
—— todoowner
delegate
def c1 = {
println "c1-this:" + this
println "c1-owner:" + owner
println "c1-delegate:" + delegate
}
c1.call()
处理:json
自带 json 处理
// to json
def p = new Person(name:"lucy",age:19)
println JsonOutput.toJson(p)
println JsonOutput.prettyPrint(JsonOutput.toJson(p))
// from json
def str = '{"age":19,"name":"lucy"}'
def js = new JsonSlurper()
def p2 = (Person)(js.parseText(str))
println p2
三方 json 处理 (gson)
import com.google.gson.Gson
// to json
def p = new Person(name:"lucy",age:19)
def gson = new Gson()
println gson.toJson(p)
// from json
def str = '{"age":19,"name":"lucy"}'
def p2 = gson.fromJson(str, Person.class)
println p2
处理:xml
final String xml = '''
<students>
<student id="1">
<name>张三</name>
<age>18</age>
<sex>男</sex>
<score>98</score>
</student>
<student id="2">
<name>李四</name>
<age>21</age>
<sex>女</sex>
<score>93</score>
</student>
</students>
'''
// from xml
def xs = new XmlSlurper()
def students = xs.parseText(xml)
println students.student[0].name.text() // 获取节点值
println students.student[1].@id // 获取属性值
// to xml
import groovy.xml.MarkupBuilder
def s = new StringWriter();
def mb = new MarkupBuilder(s)
mb.students() { // 💡看上去像方法,但并非方法,只是语法相似
student(id:'1') { // (prop:value) 传入属性值
// {} 传入节点
name(a:'a', '张三') // (prop:value,...,content) 传入节点内容
age(18)
// ...
}
}
println s
Maven 项目
都用 Groovy 了,就直接 Gradle 走起!
<dependencies>
<dependency>
<groupId>org.apache.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>4.0.14</version>
<type>pom</type>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.gmavenplus</groupId>
<artifactId>gmavenplus-plugin</artifactId>
<version>1.13.1</version>
<executions>
<execution>
<goals>
<goal>execute</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.apache.groovy</groupId>
<artifactId>groovy</artifactId>
<version>4.0.14</version>
<scope>runtime</scope>
</dependency>
</dependencies>
<configuration>
<scripts>
<script>src/main/groovy/Main.groovy</script>
</scripts>
</configuration>
</plugin>
</plugins>
</build>