新Helper,类库和APIs
Groovy向已有的Java类,如java.lang.Object,java.lang.String,java.util.List等等,增加了一系列实用方法,以扩展JDK类库。Groovy到底是依靠什么技术为已有的Java类动态增加方法呢?答案就是元编程(metaprogramming)。在Java中,类一旦被加载就不允许再被修改。而Groovy的所有类在被加载时,都会与一个元类(metaclass)相关联。metaclass如同代理一样,将方法调用委托给真正的实现代码去处理。第4章将会详细讨论元编程。
同样,Groovy增加了一系列新的帮助类(Helper Classes),帮助开发者完成各种繁琐的工作,如数据库访问,单元测试,构造标记语言,处理XML(Extensible Markup Language,可扩展标志语言)和GUI编程等。
除了提供给java.lang.String帮助方法外,Groovy还引入了新的字符串类GString,它是groovy.lang.GString的实例。GString允许占位符嵌入到字符串中,如 “Hello, my name is ${name}”。
最后,Groovy很好地支持正则表达式,而且还引入3种操作符以简化正则表达式操作:
l 模式(Pattern)操作符:~Pattern
l 查找(find)操作符:=~
l 匹配(match)操作符:==~
GDK
GDK是已有的JDK类的Groovy扩展。清单2.10展示了Groovy向java.lang.Object,java.lang.Number和java.io.File等类增加的新方法。Groovy GDK 大约共有60个增强类(enhanced classes)。完整的GDK API规范可参考http://groovy.codehaus.org/groovy-jdk。
清单2.10 GDK的应用
//java.lang.Object
def a = [1,2,3]
assert a.any {it > 2} //At least one element satisfies the condition
assert a.every{it > 0} //All elements must satisfy the condition
//Iterate over all the elements calling the closure on each item
assert a.collect{it * 2} == [2,4,6]
assert a.findAll{it > 2} == [3] //Finds all elements that satisfy the condition
a.print(a) //Prints the values of a, can be also written as print(a)
//java.lang.Number
def x = 10
assert x.abs() == 10 //Returns absolute value
assert x.compareTo(3) == 1 //Compares two numbers
assert x.div(2) == 5 //Divides two numbers
def total = 0
x.downto(5) {
number -> total += number} //Sums the numbers from 10 to 5 inclusive
assert total == 45
total = 0
x.upto(15){
number -> total += number} //Sums the numbers from 10 to 15 inclusive
assert total == 75
//java.io.File
def f = new File("C:\\temp\\groovy.txt") //Marks a file for creation
f.text = "Groovy rocks!" //File will be created if it doesn't exist
assert f.exists()
assert f.text == "Groovy rocks!"
f.append("Doesn't?") //Appends text to the file
assert f.text =="Groovy rocks!Doesn't?"
f.renameTo(new File("C:\\temp\\groovyRenamed.txt")) //Renames a file
assert f.name == "groovy.txt" //Files are immutable
[new File("C:\\temp\\groovy.txt"),new File("C:\\temp\\groovyRenamed.txt")].
each{it.delete()} //Deletes both files
字符串和GStrings
Groovy支持两种字符串:一般字符串,它是GDK增强后的java.lang.String的实例;和GString,它是groovy.lang.GString的实例。与一般字符串相比,GString支持占位符,并且变量在运行期被解释和赋值。
不同于Java,Groovy能以多种方式声明字符串:
l 单引号:等同于在Java 中声明字符串,但不支持GString。
def text = 'Welcome to Groovy'
assert text as java.lang.String
l 双引号:支持GString。若要显示美元符号($),则必须这样写:\$。
def language = "Groovy"
def text = "Welcome to $language"
assert text == "Welcome to Groovy"
assert text as groovy.lang.GString
l 三个连续单引号:可直接跨越数行并且在输出中包含回车符、制表符和空格符,但不支持GString。
def text = '''
Welcome to Groovy
-------------------------
'''
assert text == "\nWelcome to Groovy\n-------------------------\n"
l 三个连续双引号:类似于“单个联系单引号”,但支持GString,是在Groovy中声明字符串最通用的方法。
def language = "Groovy"
def text = """
Welcome to $language
--------------------
"""
assert text == "\nWelcome to Groovy\n--------------------\n"
GDK向String类中添加很多实用的方法,清单2.11演示了其中一部分方法。第3章3.1节将详细讨论Groovy中的几种String。
清单 2.11 Groovy字符串应用
def text = "Welcome to Groovy"
//Both methods return the size of a String
assert text.size() && text.length() == 17
assert text.substring(0,7) == "Welcome"
assert text.contains("Welcome")
//Count number of occurences of a word in a String
assert text.count("Welcome") == 1
text += "\nWhat a great language"
//Decide whether a String can be parsed as a number or not
assert text.isNumber() == false
//Reverse a String
assert text.reverse() =="egaugnal taerg a tahW\nyvoorG ot emocleW"
assert text.findAll{it > 'w'} == ['y'] //Finds all characters greater than 'w'
assert text.replace('Groovy','Java') == 'Welcome to Java\nWhat a great language'
正则表达式(Regular Expressions)
正则表达式(Regular Expressions,有时简写为regexes)可以帮助您从文本中识别并提取符合指定特征的文本字符串。正则表达式是字符串模式匹配的一种方法,它通过定义一系列匹配符来匹配字符串中任何可能的模式。例如,使用正则表达式可查找一段文本中以 “ion”结尾的所有单词,或者查找“color red”的出现次数。
关于正则表达式的完整讨论已经超出本书的范围。当然,目前已有regexes方面的书籍出版[1]。最常用的正则表达式模式元素,可参考本书第3章3.2节。正则表达式模式(pattern)可由Groovy slashy(slash,斜线"/")语法来定义。模式用一个“//”给括起来,因此在模式中不需转义反斜线(backslashes,“\”):
def pattern = /abc/
assert pattern == 'abc'
pattern = /\s\d/
assert pattern == '\\s\\d'
注:Groovy还有一种定义字符串的方法,就是所谓的斜线(slashy)语法。通常这种语法用来定义正则表达式,因为它能避免像Java那样引入很多转义字符。例如,使用Slashy语法,可避免像Java那样正则表达式中使用过多的反斜线。
这对于Java 程序员来说绝对是个好消息,因为Java中多数的正则表达式模式包含大量需要转义的反斜线。
除此之外,Groovy引入3种正则表达式操作符:
l 模式操作符:~,定义一个Regex模式,即java.util.regex.Pattern实例;
l 查找操作符:=~,查找文本中符合指定模式的字符串,会返回一个java.util.regex.Matcher实例;
l 匹配操作符:==~,根据提供的正则表达式来匹配整个字符串,将返回Boolean值。
清单2.12 演示了Groovy正则表达式的应用示例,让读者了解一下Groovy Regex。
清单2.12 Groovy的正则表达式应用
text = "Information technology revolution"
pattern = /\b\w*ion\b/ //Pattern: a word that ends with the letters 'ion'
assert text =~ pattern
def matched = []
//Find all matches of the pattern
text.eachMatch(pattern) { match -> matched += match[0] }
println matched
assert matched.size() == 2
assert matched[0] == "Information"
assert matched[1] == "revolution"
[1] Nathan A. Good, Regular Expression Recipes: A Problem- Solution Approach (Berkeley, CA: Apress, 2004).