1. 默认导入
以下包和类会被Groovy自动引入
- java.io.*
- java.lang.*
- java.math.BigDecimal
- java.math.BigInteger
- java.net.*
- java.util.*
- groovy.lang.*
- groovy.util.*
2. 函数重载
在Groovy中,方法在运行时被选择,方法基于运行时参数的类型而选择;在Java中正好相反,方法基于参数声明的类型,在编译时被选择。
下面代码是用java写的,可以被Java和Groovy编译,但是结果却不同:
int method(String arg) {
return 1;
}
int method(Object arg) {
return 2;
}
Object o = "Object";
int result = method(o);
在Java中,结果为:
assertEquals(2, result);
然而在Groovy中,结果为:
assertEquals(1, result);
这是因为Java使用静态的方法,o
被声明为Object
,然而Groovy在运行时选择。
3. 数组初始化
在Groovy中,{...}
被当成闭包,所以你不能用{...}
来创建数组,只能用[...]
:
int[] array = [1,2,3]
4. 包的作用域
在Groovy中,省略属性的修饰符默认不是包访问权限:
class Person {
String name
}
属性默认会有getter和setter方法,也可以用.
访问,如果想创建一个有包访问权限的属性,可以加一个@PackageScope
注解:
class Person {
@PackageScope String name
}
5. 自动资源管理
源自Java 7 的自动资源管理并未在Groovy中得到支持,相应的,Groovy提供了另外一种依靠闭包的更符合习惯的方法,例如在Java中:
Path file = Paths.get("/path/to/file");
Charset charset = Charset.forName("UTF-8");
try (BufferedReader reader = Files.newBufferedReader(file, charset)) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
在Groovy中可以更加简洁:
new File('/path/to/file').eachLine('UTF-8') {
println it
}
还有一种更像Java的写法:
new File('/path/to/file').withReader('UTF-8') { reader ->
reader.eachLine {
println it
}
}
6. Lambdas
java8中的Lambdas表达式
Runnable run = () -> System.out.println("Run");
list.forEach(System.out::println);
java8中的Lambdas或多或少被认为是匿名内部类,Groovy不支持这种写法,但是有闭包代替:
Runnable run = { println 'run' }
list.each { println it } // or list.each(this.&println)
7. GStrings
双引号引起来的字符串是GString
,单引号引起来的是String
,单引号引起的字符串不支持$占位符写法.