天天看点

《Groovy官方文档》1.3 Groovy和Java比较

原文地址     译文地址  译者:jackwang

groovy语言一直在努力亲近java开发人员。在设计groovy语言的时候,我们遵循最小标新立异原则,努力让那些java开发背景的开发者容易上手并学会。下面我们列举groovy和java的一些主要区别。

下面的包和类是默认导入的,也就是说不必精确使用 import 语句来导入它们:

java.io.*

java.lang.*

java.math.bigdecimal

java.math.biginteger

java.net.*

java.util.*

groovy.lang.*

groovy.util.*

在groovy里,方法的调用是在运行时动态决定。这一特性叫做运行时分发(runtime dispatch)或动态方法(multi-methods)。也就是说方法的最后调用是根据传入参数在运行时的类型所决定。在java里,这一点是不一样的:在编译时就决定了方法的参数类型。

下面的代码,我们采用java风格,在groovy和java都可以编译通过,但是运行结果不一样:

在java里,结果是

但是groovy里,结果是

assertequals(1, result);

原因是java使用的是静态声明的类型信息,这里o被声明为object,但是groovy是在运行时决定,当方法最终被调用时,因为这里o实际是一个字符串,因此最终string版本的方法被调用。

译者注:译者之前也没有接触过groovy语言,空闲时间也是有限的(姑且让我找这个借口吧,虽然这个借口很牵强,对待知识本来应该以一种严谨,求真的态度)因此这里有些专有名字可能翻译不是很准确,比如对multi-methods的翻译。译者也不确定是否准确,因此附带了原文单词,请读者自行根据示例代码和上下文意思理解。如果找到准确的中文翻译恳请评论留言,以待修正。

在groovy,{…}已经被用作闭包,也就是说你不能使用下面的语法创建数组(译者注:java可以,并且很常用)

你应该这样声明并初始化一个数组

在groovy里,省略字段的修饰符不会像java一样使其成为包私有属性(package-private field)

这里,我们创建了一个属性,它是私有的,而且自动关联了getter和setter方法。如果我们要创建一个包私有属性,可以添加@packagescope注解来实现:

arm(automatic resource management 自动资源管理)块从java7开始支持,但是groovy不支持。相应地,groovy依赖于闭包来实现类似的功能。示例:

在groovy里可以写成:

或者也可以写成跟java类似风格:

groovy遵循了java的匿名内部类以及嵌套内的特点。但是它并没有完全依照java语言规范,因此在使用前应该记住它们是有区别的。groovy的实现和groovy.lang.clouser类的风格有些类似,但也有不同点。比如在访问私有字段和方法以及局部变量没有final等。

这是一个静态内部类的例子:

使用静态内部类是一个非常好的实践,如果你一定要使用内部类,建议优先考虑静态内部类。

在java里,你可以这样写:

groovy不支持y.new x()语法,但你可以写成new x(y),像下面的代码:

特别注意,groovy支持调用无参方法传入一个参数。那个参数的值将会是null。这个特性对于调用构造函数同样适用。可能会有人写new x(this)而不是new x(),这是不合法的。虽然我们还没有找到办法避免用户这样写。

java 8 支持拉姆达表达式和方法引用

java8的拉姆达表达式或多或少被认为是匿名内部类。groovy不支持这样的语法,但是可以使用闭包代替:

使用双引号修饰的字符串被解释为gstring值。如果一个字符串里含有美元符号在groovy和java的编译器里将会产生编译错误。

当然,groovy会自动在gstring和string之间进行类型转换,就像java可以接受一个object参数然后检查其实际类型一样。

在groovy里,使用单引号修饰的被当成string类型,使用双引号修饰的可以当成gstring类型或string类型。取决于字面常量。

如果声明是char类型,groovy会自动将单个字符从string类型转换为char类型。如果被调用的方法声明的参数类型是char,我们需要强制类型转换为char类型。

groovy支持两种风格的类型转换,在转换成char类型的时候,当个字符和多个字符转换有些不一样。对于多个字符转换成char类型,groovy会选择第一个字符,这一点不像c语言,会直接失败。

在java里,==意味着基本类型相等或对象类型相等。在groovy里,==会转换成a.compareto(b)==0,如果他们是comparable,就是使用a.equals(b),否则检查基本类型,也就是is,比如a.is(b)

groovy比java有更多的关键字,请不要把它们当变量名使用

in

trait