Groovy学习笔记
1.概念
Groovy是一种具有Python、Ruby等动态语言特性的与Java平台紧密结合的敏捷开发语言。Groovy的主要设计目的就是为Java开发者提供灵活的脚本语言,它的语法类似Java 的语法,所以如果你熟悉Java的话能很快上手。
“工欲善其事,必先利其器”,Groovy没有专门的IDE,有别的Java IDE的插件,我这里采用配置Editplus来做为Groovy的开发工具,可以在网上找到Editplus中groovy的语法高亮文件和自动完成文件。
开发环境设置:
编辑器:EditPlus2.2
Jdk :1.5.0_02
Groovy:Groovy 1.0-jsr-04-SNAPSHOT
设置环境变量:
JA VA_HOME=C:\jdk1.5
GROOVY_HOME=c:\groovy(我的机器上的目录)
Path=%JAVA_HOME%\bin;%PATH%;%GROOVY_HOME%\bin
编写几个批处理文件:
%GROOVY_HOME%\bin\runjava.bat:
修改%GROOVY_HOME%\bin\asmifier.cmd:
修改%GROOVY_HOME%\bin\ classchecker.cmd:
java_withgroovy.bat:
javac_withgroovy.bat:
在EditPlus中分别配置用户工具:
配置运行Groovy脚本的工具,直接运行编辑的groovy脚本
配置编译Groovy文件的工具,可以将groovy文件编译成java的class文件
配置运行用groovy编译好的class工具
Groovy的主要特性:
Closure(闭包)的支持
本地的List和Map语法
Groovy标记:支持多种标记语言,如XML、HTML、SAX、W3C DOM Groovy Path表达式语言:类似Xpath
Groovlet:用简单的Groovy脚本实现Servlet
Groovy SQL:使得和SQL一起工作更简单
Groovy Bean:和Bean一起工作的简单语法
Groovy模版引擎:简单使用,集成了Gpath和编译成字节码
Ant脚本化
正则表达式:简洁的脚本语法使用正则表达式
操作符重载:使Collection和Map的数据类型简单化
多形式的iteration和Autoboxing
直接编译成Java字节码,很干净的和所有已存在的Java对象和类库一起工作
Groovy可以作为javac的一种可选编译器来生成标准的Java字节码,在任何Java工程中使用。Groovy可以作为一种动态的可选语言,如脚本化Java对象、模版化、编写单元测试用例。
工具介绍:
Groovy :运行groovy脚本文件。
Groovyc:编译groovy脚本成java的bytecode文件(.class)
Groovysh:运行命令行的控制台,可以输入groovy语句直接执行
GroovyConsole:GUI形式的控制台,相当于简单的编辑器
2.基本语法
2.1.1.1.语法类似于Java,如果是单行写一条语句可以不用“;”结尾;若一行写多条则需用“;”隔
开。如下所示:
个人认为无论什么时候最好都用“;”做为语句结尾,避免不必要的错误。
2.1.1.2.在groovy中语句可以跨多行。如下:
在语句较长、较复杂的时候有用。
2.1.1.
3.支持表达式,如下:
2.1.1.4.可以直接使用java的类,可以调用java的方法,甚至在表达式当中也可以使用,如下:
2.1.1.5.在groovy中定义方法同java基本类似,只是return关键字可以不写,返回类型也可以不
写(默认是Object)。调用方法时可以不用括号,只要有参数,并且没有歧义,例如前面例子中的println方法。
2.1.1.6.传递命名参数。在调用方法时,可以传递命名参数,参数的名字和值用分号分隔(象Map
语法),参数名是唯一标识字符串。当前这种方法传递只实现具有Map的方法调用或
JavaBean构造。
2.1.1.7.传递闭包给方法,闭包是groovy的主要特性之一,它的特点是只有单一的方法可以调用,
但可以有多个参数。闭包用“{}”括起,“|”前面是参数,后面是处理语句,使用call调用。
闭包也可以嵌套使用。如下:
例子中首先定义一个闭包closure,然后定义一个方法foo,它接受一个闭包参数后在方法
中进行调用,第一个调用是普通的传参数给闭包,第二个是将一个List通过一个闭包处理
后再传给temp一个List参数。
2.1.1.8.在groovy中,如果没有指定变量类型,这个称为动态类型,此时方法可以动态调用。也可
以使用强制类型来声明变量,称为静态类型。比较下面两段代码:
第一段代码没有错,第二段代码会抛出类型转换异常
2.1.1.9.可以通过“.属性名”访问属性,如下:
定义属性的时候可以使用“@Property”,也可以是“def
2.1.1.10.Groovy在语法上跟java有几点不同。
Groovy中,”= =”等同于java中的equals方法;”= = =”等同于java中的”= =”。
Groovy中缺省的标志符是public。
3.字符串
3.1.1.1.Groovy中的字符串是用一对单引号或一对双引号来定义的,并且可以嵌套使用,也就是
说在双引号定义的字符串中可以有单引号,在单引号定义的字符串中可以有双引号,互
不影响。例如:
输出结果是:
3.1.1.2.Groovy支持在字符串中包含表达式。${
候才会求值的。例如:
输出结果:
写较长的Sql时省得用那么多+号了。
3.1.1.3.对于大段的文字可以用三个引号来定义,例如:
3.1.1.
4.Groovy中的字符串除了可以直接调用java中字符串的方法,还有一些自己的方便使用的
方法,如下例:
输出结果:
例中调用了eachMatch方法,它可以根据正则表达式在字符串中找到符合的子串做为参数传给闭包并执行。
4.集合
Groovy中的集合是体现其方便性的一个亮点,支持Collection、List、Map和数组,Groovy中还提供了一种特殊的类型——范围(Ranges)。下面分别按照Ranges,Lists,Maps分别介绍。
4.1.1.1.Ranges,顾名思义就是指明范围的一个列表。在Groovy中,Ranges其实是java.util.List的
一个实现,它具有以下特点:
a.它里面的值是连续的。
b.因为是扩展自java.util.List,所以可以做为List使用
c.定义时如果是“..”定义的,则包含两个边界;如果是“...”定义的则不包含
右边界。
示例:
结果如下:
例中的each方法是List的方法,可以遍历List当中的每个元素,${it}是指传给闭包
的每个参数,如果只有一个参数时可以这样写。
4.1.1.2.Lists,List的定义是包括在一对“[ ]”间的值,如果没有值的话就是一个空的List。
输出:
示例中的每个变量都是java.util.List的实现。
4.1.1.3.Maps,Map就是键值对的集合。它的定义语法如下:
输出结果:
4.1.1.4.除了一般的操作外,Groovy中的集合及字符串还支持通过下标操作符访问,即可以使用[]
像操作数组元素一样进行操作,其中Map的下标不是数值,而是它的键值。下标操作符还可以和Range结合起来进行操作。具体例子如下:
输出结果:
下标操作的另一个方便之处在于可以使用负值访问,比如:上例中的testList[-1]的值就是5。下面是详细的例子:
输出结果:
5.类和闭包
5.1.1.1.闭包类似于java中的内部类,区别在于闭包中只有一个函数定义,参数可以有多个,按
你设计想有多少个都行。前面的例子中就多次用到了闭包,闭包的作用很丰富,可以充分发挥你的想象来设计。
输出结果:
注意:将闭包传递给方法时, 有的要求 “{“要和方法调用在同一行上;如果要独立放一行,必须使用();否则会出错的,不过我试了下,还是能正常运行的,不过既然说了,肯定有一定道理,暂且做为语法要求吧。
5.1.1.2.类:
Groovy中的类定义同java中的类似。
Groovy的不同地方:缺省是public
Groovy支持JavaBean机制:GroovyBean
每个Groovy类都是字节码/JVM级的Java类,任何方法对Java都是有效的,反之亦然
可以指定方法的参数类型和返回类型,这样可以在通常的Java代码中更好的工作
可以用上面的方式来实现接口或重载方法
输出结果:
如果将例子中的getAge()方法注释掉,就会输出下面的结果。
所以如果定义setter或getter方法,最好配对使用,除非只是想定义只读或只写属性。
另外,Groovy的类并不支持static块,反正我没试成功。
6.控制语句
在Groovy中,控制语句的写法同java中的差不多,循环语句有for,while,do..while(这个没试成功,应该是不支持,但有的地方说支持),判断语句有if..else,switch及三元操作符(类似于java中的expr?
6.1.1.1.if..else:同java中的一样。
例:
输出:
6.1.1.2. switch语句:Groovy中的switch功能很强大,可以做任何类型的值的匹配。
case值为类名匹配switch值为类实例
case值为正则表达式匹配switch值的字符串匹配该正则表达式
case值为集合匹配switch值包含在集合中,这包括ranges
除了上面的,case值与switch值相等才匹配
例:
输出结果:
6.1.1.3.while循环。语法没什么特殊之处,跟java一样
输出:
6.1.1.4.for循环,Groovy中的for循环很好用的,它能够和各种类型的数组、集合、范围、Map等结
合起来用,一般的那种用法不行,这点可以理解,使用Range比那种方法简捷明了,不过支持下也无所谓吧。
7.操作符重载
在java中消失的操作符重载在Groovy中获得了支持,使得数值、集合、Map和其它种类的数据结构更容易使用。具体请参考groovy-reference-card 来使用。
输出:
8.I/O操作
在Groovy中,对Java Reader/Writer、InputStream/OutputStream、File和URL提供了很多有用的方法来处理I/O操作。使用闭包允许处理资源时确保正确关闭而不管是否有异常,如果在闭包中读取文件时发生异常,资源也可以正确关闭。
例1:
输出:
例2:
输出:
例3:
输出:
9.高级应用
Groovy Sql:Groovy Sql提供了易于访问数据库的方法,也不用关心资源的释放,你可以写出简洁的数据库访问语句。例如:
输出:
更多方法请看groovy-reference-card
Groovy Math:
Groovy Math提供了类似于Java中的Math类的操作,不同之处在于Groovy中默认使用BigDecimal来计算。如果想得到指定类型的对象,可以在数字后面加后缀来表示,例如:L为Long 型的;B为BigInteger型的;I为Integer型的;D为Double型的;F为Float型的。Groovy也支持用加前缀的方式来表示十六进制或八进制数,例如:前缀为0x表示是十六进制数;前缀为0表示是八进制数。
Groovy Math的操作同java中的一样,同样也会在二元操作中自动转换参数类型。除了除法外,一般的操作是将数据类型转为两个操作数中精度最高的;在除法中,如果有操作数为Float或Double,则结果为Double型,否则都是BigDecimal型。
例1:Groovy中默认的是BigDecimal类型
运行结果如下:
例2:在Groovy中进行二元操作会自动转换参数类型
GroovyMarkup:
Groovy对XML、HTML、W3C DOM、Ant Tasks和Swing user interfaces中的各种标记语言提供本地支持,它的语法很简洁,下面的例子是我从Groovy Home中的一个例子修改的,它以少量的代码展示了如何使用Groovy的特性创建一个简单的窗口程序。
例:
import groovy.swing.*;
class temp{
public String key;
public String value;
}
/**定义一个List对象*/
someBean=[
new temp(key:"key1",value:"First"),
new temp(key:"key2",value:"Second")
];
swing = new SwingBuilder();//定义swing的构造类对象
//下面就是产生一个窗体的代码,
widget = swing.frame(
title:"My Frame",
defaultCloseOperation:javax.swing.WindowConstants.EXIT_ON_CLOSE ) {
panel() {
for (entry in someBean) {
label(text:entry.key);
textField(text:entry.value);
}
button(
text:"OK",
actionPerformed:{ println("I've been clicked")
}
)
}
};
widget.show();
输出图示窗体:
当点击“OK”按钮时,控制台输出:
与ant集成:
在groovy-reference-card 中有下面的代码示例:
10.正则表达式
Groovy支持在字符串前加'~'表示正则表达式,同时支持'=~'操作,该操作产生一个Matcher对象。如下例:
输出结果:
11.参考资料
Open Java Project https://www.wendangku.net/doc/8f4876454.html,/chenyun2000/
Groovy Home https://www.wendangku.net/doc/8f4876454.html,/
总的来说,Groovy还是比较简单的,但是很强大,对于Java来说是个很好的支持。