Groovy基础语法详解
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Groovy基础语法详解相关的知识,希望对你有一定的参考价值。
参考技术A GroovyDoc 遵循与 Java 自己的 JavaDoc 相同的约定,可以使用与 JavaDoc 相同的标签。引号标识符出现在表达式 . 后面。 例如,person.name 表达式的名称部分可用引号引起。例如 person.“name” 或 person.'name'。
当某些标识符包含被 Java 语言规范禁止的非法字符,但使用引号引起时在 Groovy 中是允许的。 例如,像破折号,空格,感叹号等字符。
单引号字符串为 java.lang.String,不支持插值。
三重单引号字符串为 java.lang.String,不支持插值,三重单引号字符串是多行的,不要用换行符来换行。
用于键盘上不存在的字符。
以下
三重双引号字符串表现和双引号字符串一样,另外它是多行的。
与 Java 不同,Groovy 没有明确的字符字面量。 但可以通过三种不同的方式明确地将 Groovy 字符串设置成字符类型。
若使用 def 关键字声明,则类型取决于该值所兼容的类型。
二进制数字以 0b 前缀开头:
八进制数字以 0 前缀开头:
十六进制数字以 0x 前缀开头:
使用后缀强制一个数值的类型:
幂运算符由 ** 运算符表示,其中有两个参数:基数和指数。 幂运算符的结果取决于其操作数和操作结果。
Groovy入门 | 基础语法
- Java的东西Groovy都能用,包括语法和类库
public static void main(String[] args) {
// 重要的事情说3遍
for (int i = 0; i < 3; i++) {
System.out.println("Java的东西Groovy都能用");
}
// 再3遍
for (i in 0..2) {
println ‘Java的东西Groovy都能用‘
}
// 又3遍
3.times {
println ‘Java的东西Groovy都能用‘
}
}
1)Groovy继承了Java的所有东西,就是你突然忘了Groovy的语法可以写成Java代码,也就是Groovy和Java混在一起也能执行。
2)Groovy和Java一样运行在JVM,源码都是先编译为class字节码。
3)Groovy又对Java的语法进行了简化,功能进行了扩充。
- 自动导入常用包
java.lang
java.util
java.io
java.net
java.math.BigDecimal
java.math.BigInteger
groovy.lang
groovy.util
- 语句不需要分号结尾
写了也没事
- 注释
// 单行注释
println "hello groovy,"
/*
多行注释
*/
+ "I‘m Atlas."
- 关键字
as、assert
break
case、catch、class、const、continue
def、default、do
else、enum、extends
false、finally、for
goto
if、implements、import、in、instanceof、interface
new、null
package
return
super、switch
this、throw、throws、trait、true、try
while
- def 和类型
1)def可以声明任何类型的变量。
2)def定义带有无类型参数的方法时,可以这样:
void doSomething(def param1, def param2) { }
也可以这样:
void doSomething(param1, param2) { }
- 访问修饰符默认采用 public
Groovy的类和方法的默认修饰符都是public,且可以省略不写。由于修饰符可以省略、方法返回类型可以省略、方法参数类型可以省略。所以Java的类和main方法的结构可以简化为:
class HelloGroovy {
static main(args) {
}
}
- 可选择性使用的 return 关键字
String toString() { return "a server" }
可写成:
String toString() { "a server" }
- 省略括号
对于顶级表达式,Groovy 允许省去括号,比如 println 命令:
println "Hello"
- 标识符
1)标识符以字母、$、_开头,不能以数字开头,但后面可以跟数字。
2)字母的的取值区间为:
‘a‘ to ‘z‘ (lowercase ascii letter)
‘A‘ to ‘Z‘ (uppercase ascii letter)
‘u00C0‘ to ‘u00D6‘
‘u00D8‘ to ‘u00F6‘
‘u00F8‘ to ‘u00FF‘
‘u0100‘ to ‘uFFFE‘
3)Groovy提供了不同种类的字符串字面量,所有String类型的字面量都允许写到.后作为引用标识符。
def map = [:]
map."an identifier with a space and double quotes" = "ALLOWED"
map.‘with-dash-signs-and-single-quotes‘ = "ALLOWED"
assert map."an identifier with a space and double quotes" == "ALLOWED"
assert map.‘with-dash-signs-and-single-quotes‘ == "ALLOWED"
map.‘single quote‘
map."double quote"
map.‘‘‘triple single quote‘‘‘
map."""triple double quote"""
map./slashy string/
map.$/dollar slashy string/$
- 字符串
字符
char c1 = ‘A‘ // 类型声明为char
assert c1 instanceof Character
def c2 = ‘B‘ as char // 通过as将类型强制指定为char
assert c2 instanceof Character
def c3 = (char)‘C‘ // 通过类型转换
1)单引号是输入什么就是什么。
// 单引号
println(‘a single quoted string‘)
assert ‘ab‘ == ‘a‘ + ‘b‘
执行结果为:
a single quoted string
2)三引号是输出一段文本,可以直接的加空格和换行。
println(‘‘‘这是一段文本。
换行啦!!!
前面有四个空。。。
又换行啦!!!‘‘‘)
执行结果为:
这是一段文本。
换行啦!!!
前面有四个空。。。
又换行啦!!!
3)双引号可以用$引用变量的值。
// 双引号
def name = ‘Atlas‘
def greeting = "Hello ${name}"
println greeting
assert greeting.toString() == ‘Hello Atlas‘
def sum = "The sum of 2 and 3 equals ${2 + 3}"
println sum
assert sum.toString() == ‘The sum of 2 and 3 equals 5‘
def person = [name: ‘Guillaume‘, age: 36]
println "$person.name is $person.age years old"
assert "$person.name is $person.age years old" == ‘Guillaume is 36 years old‘
执行结果为:
Hello Atlas
The sum of 2 and 3 equals 5
Guillaume is 36 years old
4)三双引号
def name = ‘Groovy‘
def template = """
Dear Mr ${name},
You‘re the winner of the lottery!
Yours sincerly,
Dave
"""
println template
assert template.toString().contains(‘Groovy‘)
执行结果为:
Dear Mr Groovy,
You‘re the winner of the lottery!
Yours sincerly,
Dave
- 数据类型
1)整型
Groovy的整型和Java类似:
byte
char
short
int
long
java.lang.BigInteger
e.g.
// primitive types
byte b = 1
char c = 2
short s = 3
int i = 4
long l = 5
// infinite precision
BigInteger bi = 6
如果使用def声明类型,那么这个整型是可变的。它会数值的大小来匹配类型。(负数也如此)
def a = 1
assert a instanceof Integer
// Integer.MAX_VALUE
def b = 2147483647
assert b instanceof Integer
// Integer.MAX_VALUE + 1
def c = 2147483648
assert c instanceof Long
// Long.MAX_VALUE
def d = 9223372036854775807
assert d instanceof Long
// Long.MAX_VALUE + 1
def e = 9223372036854775808
assert e instanceof BigInteger
def na = -1
assert na instanceof Integer
// Integer.MIN_VALUE
def nb = -2147483648
assert nb instanceof Integer
// Integer.MIN_VALUE - 1
def nc = -2147483649
assert nc instanceof Long
// Long.MIN_VALUE
def nd = -9223372036854775808
assert nd instanceof Long
// Long.MIN_VALUE - 1
def ne = -9223372036854775809
assert ne instanceof BigInteger
2)浮点型
浮点数类型和Java类似:
float
double
java.lang.BigDecimal
e.g.
// primitive types
float f = 1.234
double d = 2.345
// infinite precision
BigDecimal bd = 3.456
浮点数类型支持指数,通过e或E实现。
assert 1e3 == 1_000.0
assert 2E4 == 20_000.0
assert 3e+1 == 30.0
assert 4E-2 == 0.04
assert 5e-1 == 0.5
为了计算的准确性,Groovy使用BigDecimal作为浮点数的默认类型。除非显示的声明float或double,否则浮点数类型为java.lang.BigDecimal。尽管如此,在一些接受参数为float或double的方法中,依然可以使用BigDecimal类型作为参数传递。
当数值过长的时候,可以使用_对数字进行分组,以使阅读更加简洁明了。
long creditCardNumber = 1234_5678_9012_3456L
long socialSecurityNumbers = 999_99_9999L
double monetaryAmount = 12_345_132.12
long hexBytes = 0xFF_EC_DE_5E
long hexWords = 0xFFEC_DE5E
long maxLong = 0x7fff_ffff_ffff_ffffL
long alsoMaxLong = 9_223_372_036_854_775_807L
long bytes = 0b11010010_01101001_10010100_10010010
数值类型后缀
BigInteger类型后缀为G或g
Long类型后缀为L或l
Integer类型后缀为I或i
Bigdecimal类型后缀为G或g
Double类型后缀为D或d
Float类型后缀为F或f
- Boolean
布尔类型是一种特殊的类型用于判断对或错:true或false。Groovy有一套特别的规则用于强制将non-boolean类型转换为bollean类型。
- List
Groovy中没有定义自己的List类型,使用的是java.util.List类型。通过一对[]包括,里面的元素以,分隔来定义一个List。默认情况下,创建的List的类型为java.util.ArrayList。
def numbers = [1, 2, 3]
assert numbers instanceof List
assert numbers.size() == 3
List中元素可以是不同类型:
def heterogeneous = [1, "a", true]
通过使用as操作符可以强制指定List的类型,或者在声明List变量时强制指定类型。
def arrayList = [1, 2, 3]
assert arrayList instanceof java.util.ArrayList
def linkedList = [2, 3, 4] as LinkedList
assert linkedList instanceof java.util.LinkedList
LinkedList otherLinked = [3, 4, 5]
可以使用[]获取List中的元素,可以使用<<向list末尾追加元素。
def letters = [‘a‘, ‘b‘, ‘c‘, ‘d‘]
assert letters[0] == ‘a‘
assert letters[1] == ‘b‘
assert letters[-1] == ‘d‘
assert letters[-2] == ‘c‘
letters[2] = ‘C‘
assert letters[2] == ‘C‘
letters << ‘e‘
assert letters[ 4] == ‘e‘
assert letters[-1] == ‘e‘
assert letters[1, 3] == [‘b‘, ‘d‘]
assert letters[2..4] == [‘C‘, ‘d‘, ‘e‘]
- Arrays
Groovy定义数组的方式和定义list的方式一样,只不过声明时需要制定类型,或者通过as来强制制定类型为Array。
String[] arrStr = [‘Ananas‘, ‘Banana‘, ‘Kiwi‘]
assert arrStr instanceof String[]
assert !(arrStr instanceof List)
def numArr = [1, 2, 3] as int[]
assert numArr instanceof int[]
assert numArr.size() == 3
//多维数组
def matrix3 = new Integer[3][3]
assert matrix3.size() == 3
Integer[][] matrix2
matrix2 = [[1, 2], [3, 4]]
assert matrix2 instanceof Integer[][]
Groovy不支持Java数组的初始化方式。
- Maps
Map定义方式为:使用[]包括,里面的元素为key/value的形式,key和value以:分隔,每一对key/value以逗号分隔。Groovy穿件的map默认类型为java.util.LinkedHashMap。
def colors = [red: ‘#FF0000‘, green: ‘#00FF00‘, blue: ‘#0000FF‘]
assert colors[‘red‘] == ‘#FF0000‘
assert colors.green == ‘#00FF00‘
colors[‘pink‘] = ‘#FF00FF‘
colors.yellow = ‘#FFFF00‘
assert colors.pink == ‘#FF00FF‘
assert colors[‘yellow‘] == ‘#FFFF00‘
assert colors instanceof java.util.LinkedHashMap
Map中通过[key]或.key的方式来获取key对应的value。如果key不存在,则返回null。
assert colors.unknown == null
当我们使用数字作为key时,这个数字可以明确的认为是数字,并不是Groovy根据数字创建了一个字符串。但是如果以一个变量作为key的话,需要将变量用()包裹起来,否则key为变量,而不是变量所代表的值。
def key = ‘name‘
def person = [key: ‘Guillaume‘] // key实际上为"key"
assert !person.containsKey(‘name‘)
assert person.containsKey(‘key‘)
person = [(key): ‘Guillaume‘] // key实际上为"name"
assert person.containsKey(‘name‘)
- Range
/ 范围从1到10
def demoRange = 1..10
// 范围从1到9
def demoRange2 = 1..<10
println(demoRange2.from) // 获取起始值
println(demoRange2.to) // 获取最大值
- 闭包
闭包是一段代码块,注意闭包也是数据类型,所以可以把闭包作为方法的参数或者返回类型。 如果我们要筛选指定数n范围内的奇数,普通写法如下:
def getOdd(n) {
for (i in 1..n) {
if (i % 2 != 0)
println i
}
}
getOdd(10)
如果要获取偶数,又要再写一个方法:
def getEven(n) {
for (i in 1..n) {
if (i % 2 == 0)
println i
}
}
getEven(10)
这两个方法其实for循环部分的内容是重合的。 而如果用闭包就不会这样了,例如下面的pick接受两个参数,一个参数n,另外一个是闭包(closure是变量名随便取)。再重复一遍闭包是一个代码块,这里传进来你想在遍历过程做什么。至于怎么把便利过程的i传递给闭包,闭包有一个隐式变量叫it,可以接收一个参数。
看代码:
def pick(n, closure) {
for (i in 1..n) {
closure(i)
}
}
// 打印奇数
pick(10, {
if (it % 2 != 0) // it代表传进来的参数,也就是上面closure(i)的i
println it
})
// 打印偶数
pick(10, {
if (it % 2 == 0)
println it
})
总之循环结构不需要自己写了,你只需要写你想在遍历过程中做什么,例如如果要打印全部数的平方可以这样:
// 平方
pick(10, {
println it **= 2
})
如果有一些行为是经常用的,你也给闭包取个名字固定下来啊就像定义变量一样。例如如果把刚才的的打印奇数、打印偶数和打印平方定义成变量可以改成这样:
def pick(n, closure) {
for (i in 1..n) {
closure(i)
}
}
// 打印奇数
def getOdd = {
if (it % 2 != 0)
println it
}
// 打印偶数
def getEven = {
if (it % 2 == 0)
println it
}
// 打印平方
def getSquare = {
println it **= 2
}
pick(10, getOdd)
pick(10, getEven)
pick(10, getSquare)
- 隐式变量it只能代表一个参数吧?闭包怎么接收多个参数?是这样的,用 -> 把参数列表和行为隔开即可。假设我们定义一个闭包接受两个参数求他们的和:
def getSum = {
x, y -> println x + y
}
getSum(3, 4) // 闭包可以直接调用
关于闭包还有个说的,就是假设你的闭包不需要接收参数,但是还是会自动生成隐式it,只不过它的值为null。也就是说,闭包至少包含一个参数。
- Getter 与 Setter
不必自己创建字段和 getter/setter,只需把这些活儿留给 Groovy 编译器即可:
class Person {
String name
}
编译后:
public class Person implements GroovyObject {
private String name;
public Person() {
CallSite[] var1 = $getCallSiteArray();
MetaClass var2 = this.$getStaticMetaClass();
this.metaClass = var2;
}
public String getName() {
return this.name;
}
public void setName(String var1) {
this.name = var1;
}
}
- 相等与 ==
Java 的 == 实际相当于 Groovy 的 is() 方法,而 Groovy 的 == 则是一个更巧妙的 equals()。
要想比较对象的引用,不能用 ==,而应该用 a.is(b)。
- 断言
可以使用 assert 语句来检查参数、返回值以及更多类型的值。与 Java 的 assert 有所不同,Groovy 的 assert 并不需要激活,它是一直被检查的。
- 异常捕捉
如果不关心 try 语句块中所要抛出的异常类型,可以只捕捉异常而忽略它们的类型。所以,像下面这样的语句:
try {
// ...
} catch (Exception t) {
// 一些糟糕的事情
}
就可以变成下面这样捕捉任何异常(any 或 all 都可以,只要是能让你认为是任何东西的词儿就可以用):
try {
// ...
} catch (any) {
// 一些糟糕的事情
}
以上是关于Groovy基础语法详解的主要内容,如果未能解决你的问题,请参考以下文章