Groovy

2024-07-10

简介

可以被视为java的一种脚本化改良版,也是运行在JVM上,可以很好的与java代码及其相关库进行交互操作
是一种成熟的面向对象编程语言,既可以面向对象编程,又可以用作纯粹的脚本语言
大多数有效的java代码可以转换为groovy代码
groovy代码比java代码更少

特点

功能强大,例如提供了动态类型转换、闭包和元编程支持
支持函数式变成,不需要main函数
默认导入常用的包
类不支持default作用域,且默认作用域为public
基本类型也是对象,可以直接调用对象的方法
支持DSL(领域特定语言)和其他简洁的语法,让代码变得易于阅读和维护
基于java语言的,完全兼容java语法

安装

groovy.apache.org/download.html下载压缩包,解压到自己的目录下
配置环境变量GROOVY_HOME为安装目录,将%GROOVY_HOME%/bin放在path环境变量中

语法

做为面向对象编程语言时可以定义类,做为脚本语言时可以不定义类
可以混淆脚本和类的定义,文件中不能定义与文件名重名的类
使用def定义变量、方法,不建议使用具体的数据类型
注释是// /** */
语句末尾的分号可以省略,以换行做为结束
默认类、方法、字段都是public修饰的

对象的属性操作

对类属性的操作本质是通过属性对应的getter、setter方法完成的

给对象赋值

对象.属性名=xxx
对象的setter方法
具名构造器(groovy类自带的)示例:new 类名(属性名: 值)

对象属性读取操作

对象.属性名
对象["属性名"]
对象的getter方法

方法

声明时参数类型、返回值类型可省略
声明时return关键字默认使用方法最后一句的返回值做为方法的返回值
调用时()可省略

结构语句

支持顺序结构、分支结构、循环结构语句(支持if-else if-elseif switch-case for for-in)

运算符

支持算术、关系、位、赋值、范围运算符

字符串

单引号
	做为字符串常量使用,没有运算能力,不支持变量引用,不支持换行
双引号
	支持变量引用${},有运算能力
多引号
	模板字符串,支持换行,不支持变量引用

数据类型

变量、属性、方法、闭包的参数以及方法返回值的类型都是可有可无的,都是在给变量赋值的时候才决定他的类型

类型转换

需要时,类型之间会自动发生类型转换

类说明

如果没有类定义,将当做script来处理,意味着文件将透明的转换为一个Script类型的类,自动转换得到的类使用原始groovy文件名做为类的名字。
文件的内容被打包进run方法,另外在新产生的类中被加入一个main方法以进行外部执行该脚本

类型

原生数据类型及包装类:与java相同
类、内部类、抽象类、接口
注解
Trait:可以看成带有方法实现的接口

权限修饰符

public、protected、private
没有可见性修饰符的类或方法自动时公共的(可以使用一个特殊的注释来实现包的私有可见性)
没有可见性修饰符的字符自动转换为属性,不需要显示setter、getter方法
如果属性声明为final,不会生成setter

集合操作

支持List、Map集合操作,并且扩展了java中的API
Map支持+、-的加减操作
可以把不同的基本类型添加到同一集合中

类导入

import导入类
默认导入了java.lang/java.util/java.io/java.net/groovy.lang/groovy.util/java.math.BigInteger/java.math.BigDecimal

异常处理

try-cache-finally

闭包

一个开放的、匿名的代码块,可以接受参数,也可以有返回值,闭包可以引用其周围作用域中声明的变量
实际开发中一般作为方法的参数使用

语法

{[closureParameters -> ] statements}

调用

第一步,给闭包赋值给一个变量
第二部,变量名()、变量名.call()

示例

{item++}
{ -> item++}
// 不指定参数时,默认使用参数it
{print it}
{name -> println name}
{String x,String y -> println "${x} ${y}"}
{ reader -> 
	def line = reader.readLine()
	line.trim()
}

闭包做为方法的最后一个参数,闭包可以写在方法外边

def aculate(Closure closure) {
	def num1 = 10
	def num2 = 15
	closure(num1, num2)
}
// 两种写法一样
caculate(){k,v -> println("$k + $v = ${k+v}")}
caculate{k,v -> println("$k + $v = ${k+v}")}

注意点

建议使用def定义,支持动态类型声明的
可以为属性自动生成getter、setter方法
方法调用时,在不引起歧义时可以省略()
变量引用时,在不引起歧义时可以省略{}


{/if}