1.groovy所有的包和classes是默认被导入

2.在groovy中,方法的调用是在运行时被选择。这被称为运行时调度和多方法。根据运行时参数类型选择方法。

    在java中,这个是相反的,在编译时,根据定义的类型, 选择方法。

以下代码以Java代码的形式编写,可以在Java和Groovy中编译,但其行为会有所不同:

1 int method(String arg) {
2 return 1;
3 }
4 int method(Object arg) {
5 return 2;
6 }
7 Object o = "Object";
8 int result = method(o);

在java中 result的值是2,

在groovy中的值是1

 

java使用的是静态信息类型,o被声明为Object;然而groovy是在运行时选择,这个方法真正被调用的时候。因为o是一个String所以调运String的版本。

 

3.数组的初始化: 在Groovy中,{…}块保留给闭包。

    java:

int[] array = { 1, 2, 3 }

    groovy

int[] array = [ 1, 2, 3]

 

4.包范围的可见性

    在groovy中,省略字段的修饰符,不会导致像在java中变成一个包私有字段。

    相反,在groovy创建一个属性,即私有字段,关联getter,关联setter

    通过注解@PackageScope来创建一个包私有字段

1 class Perso{
2     @PackageScope String name
3 }

 

5.ARM(Automatic Resource Management)模块( 自动资源管理)

    Groovy不支持Java7中的ARM模块。

    相反, Groovy提供了依赖于闭包的各种方法,闭包具有相同的效果,同时更具有惯用性

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();
}

能被写成

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.内部类

     匿名内部类和嵌套类的实现遵循Java的指导原则,但是您不应该去掉Java语言规范,而继续对不同的事情摇头叹息。实现看起来很像我们对groov.lang.Closure所做的。有一些好处也有一些不同。例如,访问私有字段和方法可能成为一个问题,但另一方面,局部变量不一定是最终的。

    静态内部类:

class A {
    static class B {}
}
new A.B()

静态内部类的使用最受支持。如果你绝对需要一个内部类,你应该设置它是一个静态内部类。

    匿名内部类:

import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
 
CountDownLatch called = new CountDownLatch(1)
 
Timer timer = new Timer()
timer.schedule(new TimerTask() {
    void run() {
        called.countDown()
    }
}, 0)
assert called.await(10, TimeUnit.SECONDS)

 

    创建一个非静态的内部类的实例

在Java中:

public class Y {
public class X {}
public X foo() {
return new X();
}
public static X createX(Y y) {
return y.new X();
}}

Groovy中不支持  y.new X() 。代替,你必须写成 new X(y), 就像下面的代码

public class Y {
public class X {}
public X foo() {
return new X()
}
public static X createX(Y y) {
return new X(y)
    }
}

 

Groovy支持使用一个参数调用方法,而不提供参数参数,那么参数的值将为null。相同的规则应用在调用构造函数上。有一个危险,你写 new X() 代替 new X(this)。 因为这可能也是常规的方法,我们还没有找到一个好的方法来预防这个问题。

7.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)

 

8.GString

    双引号的字符串的字面值被解释为GString类型的值。如果用Groovy和Java编译一个包含$符号的String,Groovy可能会编译报错或者产生微妙的不同代码

    如果API 声明的参数的类,Groovy自动转换在GString和String之间。当心Java APIs,接受一个对象的参数并且检查实际类型。

 

9.String  Character

    在Groovy,单引号字面值被使用为String,双引号的结果是 String 或者 GString,取决于在字面值中是否有插入。

    Groovy自动转换单个字符的字符串成为字符类型,仅仅是当分配的变量类型char。

    当调用参数类型是char的方法时,我们需要显示的转换 或者确保这个值被提前转换。

    Groovy支持2种风格的转换,当转换的是多个字符的字符串时,有一些不同。Groovy风格是更加宽容的,将转换第一个字符,然而C风格的转换将以exception失败

 

10.原始类型和包装类型

    因为Groovy什么都是对象,它自动引用到原始类型。正因为这样,它不遵循java的行为,扩大 优先级到装箱

    

int i
m(i)
void m(long l) { // 1
println "in m(long)"
}
void m(Integer i) { //2
println "in m(Integer)"
}

 

1.java调用这个方法,认为 扩展 优先于 拆箱

2.Groovy调用这个方法,因为所有的原始类型引用到他们的的包装类。

 

11.== 

在Java中 == 意味着 原始类型相同或 对象的一致性。

在Groovy 中  如果他们是可比较的并且a.equals(b), == 转换成a.compareTo(b)==0。为了核查一致性,可以使用is,例如 a.is(b)

 

12.转换(conversions)

 

13.额外的字段

     Groovy中的关键词比Java中的多一些。不要将它们用于变量名等

    as、def、in、trait