Groovy 试图尽可能让Java 开发人员感觉到很自然,遵循最少惊讶的原则,特别是对于来自Java背景的开发人员。
这里列出了Java 和 Groovy之间主要的不同之处。
1. 默认 import
在Groovy中,下面这些包和类会自动 impot:
- java.io.*
- java.lang.*
- java.math.BigDecimal
- java.math.BigInteger
- java.net.*
- java.util.*
- groovy.lang.*
- groovy.util.*
2. 常见的差别
1) == 表示equals,是相等的意思,可以用在所有的类型上。在Java中,== 表示基本类型相等,或表示同一个对象。在Groovy中, is() 方法可以判断是否一个对象,例如: foo.is(bar)。如果比较的是null,这种方法并不会起到作用,但是仍然可以使用 == :foo == null 。
2) in 是一个关键字,用在for 循环中:for(i in len).
3) 声明一个数组 时,这样的写法是错误的:int [] a = {1,2,3};
要写成:int [] a = [1,2,3]
4) 循环 可以写成这个样子:for (int i=0; i < len; i++) {...} ,但是计数变量只能使用一个,可以用下面的写法:
for (i in 0..len-1) {...}
for (i in 0..<len) {...}
len.times {...}
3. 需要注意的差别
- 分号 是可选的,你可以选择是否使用,但是如果把几个语句放在一行,就必须使用分号。
- return 关键字是可选的。
- 可以在 static 方法内使用 this 关键字(这时this引用当前的class)。
- 方法和类默认是public 的。
- 在 Groovy 中,protected 和 Java中的 protected 的意思相同,例如可以同一个包内可以访问友好成员,继承类也可以看见父类的 protected 成员。
- Groovy 不支持内部类,在大多数情况下,可以使用 闭包 (closure )代替。
- Groovy 编译器不检查方法语句中的 throws 语句,因为 在Groovy中,检查checked 和 unchecked 异常没有差别。
- 使用未声明的成员,或传递类型错误的参数,将不会遇到像在java中的编译错误。
4. 不常见的差别
Java程序员习惯使用分号来结束语句,并且在Java中没有闭包,在类声明中通常也会有一个类初始化模块,例如:
class Trial {
private final Thing thing = new Thing();
{ thing.doSomething () };
}
许多Groovy程序员避免使用分号(也有其他人总是使用分号--这取决于编码风格),但是如果把上边的代码写成下面的样子也会导致问题:
class Trial {
private final Thing thing = new Thing()
{ thing.doSomething () }
}
这会抛出一个 MissingMethodException异常!
这里的问题是,这种情况下的新行代码不能结束一个语句,下面的代码块是一个闭包,被当作一个参数传递给Things() 构造器。很奇怪是吧,但是这是真的。如果真的需要通过这种方法使用实例初始化模块,就必须使用一个分号:
class Trial {
private final Thing thing = new Thing();
{ thing.doSomething () }
}
5. 新加入到Groovy中但Java不具备的特性
- 闭包(closures)
- lists 和 maps 原生语法
- GroovyMarkup 和 GPath 的支持
- 正则表达式 的原生支持
- 各种各样的循环方法 和 强大的 switch 语句
- 动态和静态类型的支持--可以在方法、域和变量声明中省略类型声明。
- 可以在字符串中嵌入表达式。
- 在JDK中添加了许多帮助方法。
- 编写 beans、beans的属性,以及添加事件监听器的语法更为简单。
- 使用?. 操作符实现安全的对象导航,例如:"variable?.field", "variable?.method()",不用在嵌入 if 去检查空值了。