groovy和java的差异

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
 
posted @ 2018-08-28 09:29  璀璨菜菜  阅读(3691)  评论(0编辑  收藏  举报