groovy用户指南
???? 集合 (1)List (java.util.List) list = [1,2,'hello',new java.util.Date()]
assert list.size() == 4
assert list.get(2) == 'hello'
注意:一切都是对象(数字会自动转换) (2)Map (java.util.Map) map = ['name':'James','location':'London']
assert map.size() == 2
assert map.get('name') == 'James'
(3)遍历集合 list = [1,3]
for (i in list) { println i }
? 2、? 闭包(Closures) l???????? 闭包类似Java的内类,区别是闭包只有单一的方法可以调用,但可以有任意的参数 closure = { param -> println("hello ${param}") }
closure.call("world!")
closure = { greeting,name -> println(greeting + name) }
closure.call("hello ","world!")
l???????? 闭包用“{}”括起,“->”前面是参数,后面是处理语句,使用call调用 l???????? 第一个例子演示了在字符串内使用参数的形式:${param} l???????? 第二个例子演示了多参数形式:用“,”分隔参数 l???????? 如果只有一个参数,可以不写,而使用缺省的参数“it”,如下面的例子: closure = { println "hello " + it }
closure.call("world!")
? 3、 each l???????? 遍历集合,逐个传递给闭包 [1,3].each { item -> print "${item}-" }
l???????? 上面例子的输出结果是:1-2-3- ? 4、 collect l???????? 遍历集合,逐个传递给闭包,处理后的结果返回给对应的项 value = [1,3].collect { it * 2 }
assert value == [2,4,6]
与each区别:
value2 = [1,3].each { it * 2 }
println value2
value3 = [1,3].collect { it * 2 }
println value3
结果:
[1,3]
[2,6]
返回值不同
? 5、 find l???????? 根据闭包断言,返回集合中找到的第一个项目 value = [1,3].find { it > 1 }
assert value == 2
? 6、 findAll l???????? 根据闭包断言,返回集合中所有找到的项目 value = [1,3].findAll { it > 1 }
assert value == [2,3]
? 7、 inject l???????? 遍历集合,第一次将传递的值和集合项目传给闭包,将处理结果作为传递的值,和下一个集合项目传给闭包,依此类推 value = [1,3].inject('counting: ') { str,item -> str + item }
assert value == "counting: 123"
value = [1,3].inject(0) { count,item -> count + item }
assert value == 6
? 8、 every l???????? 如果集合中所有项目都匹配闭包断言,就返回true,否则返回false value = [1,3].every { it < 5 }
assert value
?
value = [1,3].every { item -> item < 3 }
assert ! value
? 9、 any l???????? 如果集合中任何项目匹配闭包断言,就返回true,否则返回false value = [1,3].any { it > 2 }
assert value
?
value = [1,3].any { item | item > 3 }
assert value == false
? 10、?????????????min/max l???????? 返回集合中的最小/最大项目(对象必须可比较) value = [9,10,5].max()
assert value == 10
value = [9,5].min()
assert value == 2
value = ['x','y','a','z'].min()
assert value == 'a'
? 11、?????????????join l???????? 连接集合中的值成一个字符串 value = [1,3].join('-')
assert value == '1-2-3'
? 12、?????????????yield l???????? 在Python和Ruby中通过yield语句创建“yield”风格的iterators,在Groovy同样有效,只是使用的是闭包 class Foo{
?
?????? static void main(args) {
?????????????? foo = new Foo()
?????????????? for (x in foo.myGenerator) {
??????????????????????? print("${x}-")
?????????????? }
?????? }
?
?????? myGenerator(Closure yield) { ?????????????? yield.call("A") ?????????????? yield.call("B")
?????????????? yield.call("C")
?????? }
}
l???????? 例子的输出结果是:A-B-C- l???????? Cloures原型可以省略,call和括号同样可选,这样更象Python/Ruby class Foo {
?????? myGenerator(yield) { ?????????????? yield "A" ?????????????? yield "B"
?????????????? yield "C"
?????? }
?
?????? static void main(args) {
?????????????? foo = new Foo()???
?????????????? foo.myGenerator { println "Called with ${it}" }
?????? }
}
? 1.闭包 def closure={ param -> println "hello${param}" }?? def是一个关键字,相当于JavaScript中的Var,用来定义一个对象。 所有的闭包都是继承自groovy.lang.Closure类,闭包也是一个普通的类, 闭包的返回值: 闭包可以调用的对象: 关于0个参数以及对象it: def closure2={ println "hello ${it}"}?? 关于闭包的调用: 2.集合的本地化语法 看一个来自Groovy官方网站的例子: def emptyList = [] 与Java的区别如下: 看一个Map的例子: def emptyMap = [:] 与Java的区别如下: Range的使用: range = 5..<8 几个说明 '*.'操作符号的使用: String的特殊使用: assert x == "c" def sub = text[5..10] 说明: ? --------------------------------------------------------------------------------- -------------------------------------------------------------------------------- ? 1、类 (1)类 l???????? Groovy的类定义和Java类似 ????????? 方法可以基于类(static)或实例 ????????? 可以为public、protected或private ????????? 支持常用的Java修饰符,如synchronized l???????? Groovy的不同地方:缺省是public l???????? Groovy支持JavaBean机制:GroovyBean l???????? 每个Groovy类都是字节码/JVM级的Java类,任何方法对Java都是有效的,反之亦然 l???????? 你可以指定方法的参数类型和返回类型,这样可以在通常的Java代码中更好的工作 l???????? 你可以用上面的方式来实现接口或重载方法 l???????? 如果省略方法的类型,就会使用缺省的java.lang.Object (2)脚本 l???????? Groovy支持纯脚本,而不需要声明类,如Foo.groovy包含下面的脚本: println "Nice cheese Gromit!"
l???????? 运行脚本的过程: ????????? 编译成Foo.class(还会有一些内类),该类扩展groovy.lang.Script ????????? 执行自动生成的main方法 ?????????实例化Foo类 ?????????调用run方法执行脚本内容 l???????? 可以在Java代码中执行脚本,同时还可以传递变量值到脚本中 l???????? Foo.groovy内容修改如下 println "Nice ${cheese} Gromit!"
l???????? 下面是执行脚本的UseFoo类 import groovy.lang.Binding;
import groovy.lang.Script;
?
public class UseFoo {
?????? public static void main(String[] args) {
?????????????? Binding binding = new Binding();
?????????????? binding.setVariable("cheese","Cheddar"); ??????????????
?????????????? Script foo = new Foo(binding); ?????????????? foo.run();
?????? }
}
l????????UseFoo运行的结果是:Nice Cheddar Gromit! l???????? 执行脚本的方法是创建Foo类实例,调用其run方法 l???????? Foo类有一个带Binding参数的构造函数,可以通过Binding类的setVariable方法设置值给脚本中的属性变量 l???????? Foo类有一个不带参数的构造函数,在不传递属性变量值时使用 l???????? 在脚本结束后,脚本中创建的任何变量都会在Binding中,以供在Java中访问 l???????? 再将Foo.groovy内容修改如下 println "Nice ${cheese} Gromit!"
cheese = "changed"
l????????UseFoo类修改为: import groovy.lang.Binding;
import groovy.lang.Script;
?
public class UseFoo {
?????? public static void main(String[] args) {
?????????????? Binding binding = new Binding();
?????????????? binding.setVariable("cheese","Cheddar");
??????????????
?????????????? Script foo = new Foo(binding);
?????????????? foo.run();
?????????????? println binding.getVariable("cheese");
?????? }
}
l????????UseFoo运行的结果是: Nice Cheddar Gromit!
changed
(3)脚本中的函数 l????????不同于基于Class的Groovy,纯脚本中的函数用def关键字声明 def foo(list,value) {
??? println "Calling function foo() with param ${value}"
??? list << value
}
?
x = []
foo(x,1)
foo(x,2)
assert x == [1,2]
?
println "Creating list ${x}"
? 2、闭包 (1)概述 l????????闭包是一种传递执行代码块的强大方法。 l????????可以把闭包看作Java中的匿名内类,但是只有单一的(匿名)方法。 l????????闭包可以被用作循环的一种替代方法 [1,3,4].each { println(it) }
l????????使用闭包可以使异常处理和关闭资源变得更简单,具体例子请参看Groovy SQL (2)比较闭包和匿名内类 l????????不同于Java匿名内类,Groovy 支持“true closures”:状态可以被传递到闭包外部 l????????局部变量在闭包创建时可以被使用和修改;闭包中创建的任何变量可以作为局部变量,对外部可见 l????????看下面的例子: count = 0
last = 0
[1,4].each { count += it; last = it }
println("the sum is ${count} and the last item was ${last}")
输出结果:the sum is 10 and the last item was 4 (3)闭包是普通对象 l????????闭包是在需要时被传递和调用的对象 l????????因此可以象下面一样使用: c = { println("Hello ${it}") }
c.call('James')
c.call('Bob')
l????????闭包会被编译成扩展groovy.lang.Closure类的新类 l????????下面的省略写法是等价的 c = { println("Hello ${it}") }
c('James')
c('Bob')
(4)闭包的参数 l????????闭包可以有任意数目的参数 l????????缺省情况,闭包具有单个缺省参数:“it” l????????你可以在闭包声明的开始部分指定参数列表 c = { a,b,c –> println("Hello ${a} ${b} ${c}") }
c('cheese',234,'gromit')
l????????下面是另一个使用两个参数的有用例子,在《Groovy快速入门》已经讲过: value = [1,item –> str + item }
assert value == "counting: 123"
?
value = [1,item -> count + item }
assert value == 6
? 3、集合 Groovy支持集合、List、Map和数组 (1)Lists l???????? 下面是创建List的例子,[]表示空List表达式 list = [5,8]
assert list.get(2) == 7
assert list instanceof java.util.List
?
emptyList = []
assert emptyList.size() == 0
emptyList.add(5)
assert emptyList.size() == 1
l???????? 每个List表达式都是java.util.List的实现 (2)范围(Ranges) l???????? Range允许创建连续值的列表 l???????? 由于Range扩展java.util.List,所以Range可以作为List使用 l???????? 使用..的Range是包括两个边界,使用...的Range只包括开始边界,而不包括结束边界(//我在groovy1.5中不能使用...,如果想建立不包括边界的范围,可以使用? range=5..<8) // an inclusive range
range = 5..8
assert range.size() == 4
assert range.get(2) == 7
assert range instanceof java.util.List
assert range.contains(5)
assert range.contains(8)
?
// lets use an exclusive range
range = 5...8
assert range.size() == 3
assert range.get(2) == 7
assert range instanceof java.util.List
assert range.contains(5)
assert ! range.contains(8)
//我在groovy1.5中不能使用...,如果想建立不包括边界的范围,可以使用如下 range=5..<8
l???????? Range可以用于实现java.lang.Comparable的Java对象 // an inclusive range
range = 'a'..'d'
assert range.size() == 4
assert range.get(2) == 'c'
assert range instanceof java.util.List
assert range.contains('a')
assert range.contains('d')
assert ! range.contains('e')
l???????? Range可以用于循环遍历 for (i in 1..10) {
? println "Hello ${i}"
}
(3)Maps l???????? 下面是创建Map的例子,[:]表示空Map表达式 map = ["name":"Gromit","likes":"cheese","id":1234]
assert map.get("name") == "Gromit"
assert map.get("id") == 1234
assert map instanceof java.util.Map
?
emptyMap = [:]
assert emptyMap.size() == 0
emptyMap.put(5,"foo")
assert emptyMap.size() == 1
assert emptyMap.get(5) == "foo"
l???????? Map可以象beans一样操作,但key值(类似属性名)必须为有效的String标识 map = ["name":"Gromit","id":1234]
assert map.name == "Gromit"
assert map.id == 1234
?
emptyMap = [:]
assert emptyMap.size() == 0
emptyMap.foo = 5
assert emptyMap.size() == 1
assert emptyMap.foo == 5
(4)使用下标操作符 l???????? 可以在字符串、Lists、Maps...中使用下标进行索引 text = "nice cheese gromit!"
x = text[2]
assert x == "c"
assert x.class == String
sub = text[5..10]
assert sub == 'cheese'?
map = ["name":"Gromit","id":1234]
assert map['name'] == "Gromit"?
list = [10,11,12]
answer = list[2]
assert answer == 12?
list = 100..200
sub = list[1,20..25,33]
assert sub == [101,103,120,121,122,123,124,125,133]
l???????? 可以使用下标操作符更新项目 list = ["a","b","c"]
list[2] = "d"
list[0] = list[1]
list[3] = 5
assert list == ["b","d",5]
l???????? 可以使用负索引从最后开始计数 text = "nice cheese gromit!"
x = text[-1]
assert x == "!"
name = text[-7..-2]
assert name == "gromit"
l???????? 也可以使用向后范围(开始索引大于结束索引),返回的结果是反转的 text = "nice cheese gromit!"
name = text[3..1]
assert name == "eci"
? 4、与Java的不同 (1)通用 l???????? 在Groovy中,==等价于equals(),===意味着标识比较(等同Java中的==)好像没有这个操作符=== l???????? 在Java中==意味着原类型的相等和对象的标识比较,如a==b(a和b是指向相同对象的引用) l???????? 传递闭包给方法或使用GroovyMarkup时,{要和方法的调用在同一行上,如:(本人尝试不在同一行也可,但建议遵守要求) [1,3].each { println it }
l???????? 如果要将{放在独立于方法的一行上,要使用括号() [1,3].each (
? { println it }
)
l???????? 下面的写法是无效的,会将闭包解释成独立的闭包,而不会将闭包作为方法的参数传递 [1,3].each
{
?????? println it
}
(2)应该意识到的事情 l???????? 语句后面的分号是可选的,但在同一行上有多个语句需要用分号分隔 l???????? return关键字可选 l???????? 可以在static方法内使用_this_关键字(何用?) l???????? 缺省的修饰符是public l???????? Groovy中的protected等价包的protected和Java的protected l???????? 补充:方法调用时,括号是可选的,(注意最好使用括号,以防止错误) (3)在Java中无效的Groovy新特性 l???????? 闭包 l???????? List和Map的本地语法 l???????? GroovyMarkup和Gpath的支持 l???????? 正则表达式的本地支持 l???????? 多形式的iteration和强大的switch语句 l???????? 动态和静态类型的支持 l???????? 在字符串中嵌入表达式 l???????? 增加了许多新的帮助方法 l???????? 在属性和添加事件侦听方面,简化了编写bean的语法 ? 5、Groovy Math l???????? Groovy支持访问所有的Java Math类和操作 l???????? 为了使math操作在脚本编写时尽可能直观,Groovymath模型支持文字化math操作 l???????? 缺省计算使用的是精确的小数(BigDecimal),如: 1.1 + 0.1== 1.2 返回的是true,而不是false(不象在Java中使用float或double) (1)数字的文字表示 l???????? Groovy的小数文字表示是java.math.BigDecimal的实例,而不是浮点类型(Float或Double) l???????? Float和Double可以使用后面讲的后缀(F和D)方法来创建 l???????? 小数的指数形式也支持,如12.3e-23 l???????? 十六进制和八进制也支持,十六进制前缀0x,八进制前缀0 l???????? 整数类型可以使用后面讲的后缀(I、L和G)方法来创建,如果不指定根据数值的大小使用合适的类型 l???????? 数字类型的后缀文字表示
l???????? 例子: assert42I == new?Integer("42"); assert123L == new?Long("123"); assert2147483648 == new?Long("2147483648"); //Long type used,valuetoo large for an Integer assert456G == new java.math.BigInteger("456"); assert123.45 == new java.math.BigDecimal("123.45"); //default BigDecimaltype used assert1.200065D == new?Double("1.200065"); assert1.234F == new?Float("1.234"); assert1.23E23D == new?Double("1.23E23"); (2)Math操作 l???????? Groovy的Math实现很接近Java 1.5 BigDecimal Math模型的实践 l???????? Java.lang.Number包括其子类的二元操作(除了除法)会根据下表自动转换参数类型
l???????? 注意:Byte、Character、Short都作为Integer类型 (3)除法 l???????? 除法操作“/”和“/=”在操作数中有Float或Double类型时,结果为Double类型;其它情况,结果为BigDecimal类型 l???????? BigDecimal类型的操作会这样做: BigDecimal.divide(BigDecimalright,<scale>,BigDecimal.ROUND_HALF_UP) 其中<scale>是MAX(this.scale(),right.scale(),10) l???????? 例子: 1/2 ==new java.math.BigDecimal("0.5"); 1/3 ==new java.math.BigDecimal("0.3333333333"); 2/3 ==new java.math.BigDecimal("0.6666666667"); l???????? 整型除法使用“”和“=”操作,返回整型类型 l???????? 由于“”是Java中的转义符,在字符串中使用需要转义 " x= 83 " (4)数字文字表示语法 IntegerLiteral: ?????? Base10IntegerLiteral ?????? HexIntegerLiteral ?????? OctalIntegerLiteral? ? Base10IntegerLiteral: ?????? Base10Numeral IntegerTypeSuffix(optional) ? HexIntegerLiteral: ?????? HexNumeral IntegerTypeSuffix(optional) ? OctalIntegerLiteral:??? ?????? OctalNumeral IntegerTypeSuffix(optional) ? IntegerTypeSuffix: one of ?????? i I l L g G? Base10Numeral: ?????? 0 ?????? NonZeroDigit Digits (optional)? Digits: ?????? Digit ?????? Digits Digit ? Digit: ?????? 0 ?????? NonZeroDigit ? NonZeroDigit:one of ?????? 1 2 3 4 5 6 7 8 9? HexNumeral: ?????? 0 x HexDigits ?????? 0 X HexDigits? HexDigits: ?????? HexDigit ?????? HexDigit HexDigits? HexDigit:one of ?????? 0 1 2 3 4 5 6 7 8 9 a b c d e f A B C D EF? OctalNumeral: ?????? 0 OctalDigits? OctalDigits: ?????? OctalDigit ?????? OctalDigit OctalDigits? OctalDigit: one of ?????? 0 1 2 3 4 5 6 7? DecimalPointLiteral: ?????? Digits . Digits ExponentPart (optional)DecimalTypeSuffix (optional) ?????? . Digits ExponentPart (optional)DecimalTypeSuffix (optional) ?????? Digits ExponentPart DecimalTypeSuffix(optional) ?????? Digits ExponentPart (optional)DecimalTypeSuffix (optional) ? ExponentPart: ?????? ExponentIndicator SignedInteger? ExponentIndicator:one of ?????? e E? SignedInteger: ?????? Signopt Digits ? Sign: oneof ?????? + -? DecimalTypeSuffix:one of ?????? f F d D g G ? 6、I/O l????????Groovy提供许多有用的方法来处理I/O,包括标准的Java Reader/Writer、InputStream/OutputStream、File和URL类 l????????使用闭包允许处理资源时确保正确关闭而不管是否有异常,例如下面的例子遍历文件的每一行,即使闭包中发生异常,文件也能正确关闭: import java.io.File
new File("foo.txt").eachLine { println it } l????????使用Reader/Writer:通过闭包处理资源 import java.io.File
new File("foo.txt").withReader { reader -> ?????? while (true) {
?????????????? line = reader.readLine()
?????????????? ...
?????? }
}
l????????Groovy提供简单的方法执行命令行进程,表达式返回java.lang.Process实例,具有in/out/err流(译者:没有测试过) process = "ls -l".execute() process.in.eachLine { line | println line } ? 7、逻辑分支 (1)if-else语句 l???????? Groovy提供Java相同的if-else语句 x = false
y = false
if ( !x ) {
??? x = true
}
assert x == true
if ( x ) {
??? x = false
} else {
??? y = true
}
assert x == y
l???????? Groovy也支持三元操作符 y = 5
x = (y > 1) ? "worked" : "failed"
assert x == "worked"
(2)switch语句 l???????? Groovy的switch语句兼容Java代码,不同之处在于Groovy的switch语句能够处理各种类型的switch值,可以做各种类型的匹配:类名,正则,集合,值。 ????????? case值为类名匹配switch值为类实例,可为变量,动态 ????????? case值为正则表达式匹配switch值的字符串匹配该正则表达式 ????????? case值为集合匹配switch值包含在集合中,这包括ranges ????????? 除了上面的,case值与switch值相等才匹配 x = 1.23
result = ""
switch ( x ) {
??? case "foo":
??????? result = "found foo"
??? case "bar":
??????? result += "bar"
??? case [4,5,'inList']:
??????? result = "list"
??????? break
??? case 12..30:
??????? result = "range"
??????? break
??? case?Integer:
??????? result = "integer"
??????? break
? ??case?Number:
??????? result = "number"
??????? break
??? default:
??????? result = "default"
}
assert result == "number"
l???????? switch语句的工作原理:switch语句在做匹配case值时调用isCase(switchValue)方法,缺省调用equals(switchValue),但是已经被重载成各种类型,如类,正则表达式、集合等等 l???????? 可以创建自定义的匹配类,增加isCase(switchValue)方法来提供自定义的匹配类型 ? 8、循环 (1)while和do 循环 l????????Groovy支持Java相同的while和do 循环 x = 0
y = 5
while ( y-- > 0 ) {
??? x++
}
assert x == 5
?
//个人测试不支持do..while语句 x = 0
y = 5
do {
????? x++
}
while ( --y > 0 )
assert x == 5
(2)for循环 l????????Groovy的for循环更简单,而且能够和各种类型的数组、集合、Map等一起工作 // iterate over a range
x = 0
for ( i in 0..9 ) {
??? x += i
}
assert x == 45?
// iterate over a list
x = 0
for ( i in [0,1,4] ) {
??? x += i
}
assert x == 10?
// iterate over an array
array = (0..4).toArray()
x = 0
for ( i in array ) {
??? x += i
}
assert x == 10?
// iterate over a map
map = ['abc':1,'def':2,'xyz':3]
x = 0
for ( e in map ) {
??? x += e.value
}
assert x == 6?
// iterate over values in a map
x = 0
for ( v in map.values() ) {
??? x += v
}
assert x == 6?
// iterate over the characters in a string
text = "abc"
list = []
for (c in text) {
??? list.add(c)
}
assert list == ["a","c"]
? ? 9、操作符重载 l???????? Groovy支持操作符重载,使得数值、集合、Map和其它种类的数据结构更容易使用 l???????? 在Groovy中的各种操作符被映射到对象中调用的正规方法
l???????? 注意:所有比较操作符已经对null处理了,以避免抛出java.lang.NullPointerException a = null b ="foo" assert a!= b assert b!= a assert a== null l???????? 在不同类型的数值比较之前,Groovy会自动将数值的类型转换为更大范围的数值类型,因此,下面的例子是有效的: Byte a =12 Double b= 10 assert ainstanceof?Byte assert binstanceof?Double assert a> b 10、正则表达式 l????????Groovy支持使用~”...”本地表示的正则表达式,另外还支持“=~”操作符(创建Matcher) import java.util.regex.Matcher
import java.util.regex.Pattern
// same as assert ("cheesecheese" =~ "cheese").find()
assert "cheesecheese" =~ "cheese"
// lets create a regex Pattern
pattern = ~"a*b" assert pattern instanceof Pattern assert pattern.matcher("aaaab").matches() // lets create a Matcher
matcher = "cheesecheese" =~ "cheese" assert matcher instanceof Matcher answer = matcher.replaceAll("edam") assert answer == "edamedam"
l????????Matcher缺省会调用find()方法返回boolean值,因此可以使用=~与Perl的=~操作符的简单使用保持一致 l????????对于上面的模式匹配的例子主要是演示Pattern的用法,其实可以简化为 assert ("aaaab" =~ "a*b").matches()
? 11、语句 (1)分号 l???????? Groovy使用类似Java的语法,但是语句的分号是可选的 l???????? 如果每行一个语句,就可以省略分号;如果一行上有多个语句,就要用分号来分隔 x = [1,3]
println x
y = 5; x = y + 7
println x
assert x == 12
l???????? 一个语句可以跨越多行,对于方法的参数列表或复杂的表达式,可能会这样做 x = [1,
?????? 4,6]
println(
?????? x
)
if (x != null &&
?????? x.size() > 5) {
?????? println("Works!")
} else {
?????? assert?false: "should never happen ${x}"
}
(2)方法调用 l???????? 方法调用的语法和Java类似,支持静态和实例方法 class Foo {
?????? calculatePrice() {
?????????????? 1.23
?????? }
?????? static void main(args) {
?????????????? foo = new Foo()
?????????????? p = foo.calculatePrice()
?????????????? assert p > 0
?????????????? println "Found price: " + p
?????? }
}
l???????? 注意,return关键字在方法的最后是可选的;同样,返回类型也是可选(缺省是Object) l???????? 在Groovy中方法的调用可以省略括号,只要有参数,并且没有歧义 (3)传递命名参数 l???????? 在调用方法时,可以传递命名参数,参数的名字和值用分号分隔(象Map语法),参数名是唯一标识字符串 bean = new Expando(name:"James",location:"London",id:123)
println "Hey " + bean.name
assert bean.id == 123
l???????? 当前这种方法传递只实现具有Map的方法调用或JavaBean构造 (4)传递闭包给方法 请参考《Groovy快速入门》 (5)动态方法分派 l???????? 如果变量没有使用类型强制,动态方法分派被使用,这经常被指为动态类型,而Java缺省使用静态类型 l???????? 可以在代码中混合使用动态和静态类型 dynamicObject = "hello world".replaceAll("world","Gromit")
dynamicObject += "!"
assert dynamicObject == "hello Gromit!"
?
String staticObject = "hello there"
staticObject += "!"
assert staticObject == "hello there!"
(6)属性 l???????? 通过“.属性名”访问属性 bean = new Expando(name:"James",id:123)
name = bean.name
println("Hey ${name}")
bean.location = "Vegas"
println bean.name + " is now in " + bean.location
assert bean.location == "Vegas"
l????????上面的特殊bean Expando在运行时,动态添加属性 l????????它实际上是一个行为象动态bean的Map:增加name/value对和等效的getter/setter方法,就象定义一个真正的bean (7)安全导航 l???????? 如果你在访问复杂对象时,不想遇到NullPointerException异常,你可以使用“->”而不是“.”来导航 foo = null
bar = foo->something->myMethod()
assert bar == null
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |