2.2 Java和Groovy之间的不同点?
上一节简单介绍了Java与Groovy之间的相同点,您可把Java看作Groovy的一部分,然而Groovy却并不是Java。(The previous recipe on similarities between Java and Groovy was a relatively small one as you can consider that Java is Groovy while Groovy, however, is not Java.)这是因为Groovy可看作是Java的扩展,它额外提供了大量有利于开发应用的数据和控制结构、表达式、操作符、数据类型和帮助程序等。尽管,多数Java语法元素在Groovy完全有效,但是却不是必须的,随着深入学习Groovy,您就会知道如何省略这些可选元素。
本节旨在概述Java与Groovy的不同点,具体的区别讨论将在本书其他章节详细说明。
可选的语法元素
Groovy可以选择性地使用Java中的一些语法元素,下面将给出其中可选的语法元素。
引入语句(Import Statements)
默认情况下,Groovy会自动引入以下包(package)或类:
- groovy.lang.*
- groovy.util.*
- java.lang.*
- java.util.*
- java.net.*
- java.io.*
- java.math.BigInteger
- java.math.BigDecimal
分号(Semicolons)
Groovy中语句末尾的分号是可选的,因此,以下2行代码在Groovy中是正确的:
println 'Hello World';
println 'Hello World'
但是,如果您想把上面2行代码放在1行,这时必须使用分号隔开,即
println 'Hello'; println 'World'
而下面这行代码将不会被编译通过:
println 'Hello' println 'World'
圆括号(Parentheses)
Groovy中圆括号也是可选的。以下2行代码在Groovy中是正确有效的:
println ('Hello World')
println 'Hello World'
当然,对于易混淆的代码,最好不要省略圆括号,以提高程序的可读性。不使用小括号必须要保证代码没有歧义,除了最简单的情况(如println语句),最好还是应该保持使用小括号的良好代码习惯。
返回值类型和return关键字
Groovy中,您不必指定某一方法的返回值类型,甚至不需要使用return关键字。如果您使用def关键字作为返回值类型,Groovy会在运行时依据返回值动态获得返回值类型,如清单2.1。
清单2.1关键字return是可选的
def getPi(){
3.14
}
assert getPi() in BigDecimal
assert getPi() == 3.14
Getters和Setters
Groovy引入GroovyBeans,它类似于JavaBeans,但更简洁。GroovyBeans类中的属性看起来像共有的字段(public fields),但不需明确定义getters和setters方法(除非您想改变其默认的行为),见清单2.2。
清单2.2 GroovyBeans
class Person{
String firstName
String lastName
def getName(){
firstName + '' + lastName
}
static void main(args){
def person = new Person()
person.firstName = 'Bashar'
person.lastName = 'Abdul'
assert person.firstName == 'Bashar'
assert person.name == 'Bashar Abdul'
}
}
访问权限修饰符(Access Modifiers)
Java中的类成员变量若未显式声明访问修饰符,则默认为“default”访问权限,意味着必须在同一包中它才能被访问。然而Groovy中,方法和字段都默认为共有的(public),它们在任何情况下都能被访问到。
被检查的异常(Checked Exception)
Groovy不用考虑捕捉或声明被检查的异常(Checked exceptions),因为它们已被封装为RunTimeException。清单2.3 分别使用Java和Groovy语言通过调用createNewFile()方法实现在“C:\temp”目录下新建一个groovy.txt文件。其中,Java代码的createNewFile方法需抛出IOException异常,而该异常属于Checked exception,所以您必须在try/catch代码块中处理这个异常。而Groovy则不然,因为Groovy已经把IOException异常封装为RuntimeException。您是否领略到Groovy的魅力了呢?
解释:Java是惟一采用Checked Exception的主流语言。所谓Checked Exception,就是Exception必须显式在方法签名中声明,其具有传播性。相反,Unchecked Exception则是不需要声明的Exception,比如NullPointException就是最常见的Unchecked Exception。对Java的Checked Exception的机制,有很多争议。Checked Exception的初衷是,错误是显式处理的,假若处理不了的,要明确传递给上一层,直到有一个地方来处理这个Exception,这样可以避免错误的发生。问题是,大部分情况下,Checked Exception并没有得到正确的处理,最终的结果就是把Exception显示给用户。在被误用的情况下,被调用的代码往往没有调用者协商达成一致,或者在调用者缺席的情况下就抛出CheckedException,其缺点是明显的,它要么增加无谓的处理代码,要么会破坏“开闭原则”。
清单2.3被检查的异常(Checked exceptions)
//FileCreator.java
import java.io.File;
import java.io.IOException;
public class FileCreator {
public static void main(String args[]) {
File file = new File("C:\\temp\\groovy.txt");
try{
file.createNewFile();
}catch(IOException e){
e.printStackTrace();
}
}
}
//GroovyFileCreator.groovy
class GroovyFileCreator {
static void main(args){
File file = new File("C:\\temp\\groovy.txt")
file.createNewFile()
}
}