1. 程式人生 > >groovy與java語法區別

groovy與java語法區別

。。 call 類的使用 雙引號 compareto 錯誤 cas math 這也

groovy與java語法區別

Groovy試圖對Java開發人員盡可能地兼容。在設計Groovy時,遵循最不意外的原則,尤其是對於那些來自Java背景的開發人員。
這裏我們列出了Java和Groovy之間的所有主要區別。

1.額外的關鍵字

Groovy中比Java多一些關鍵字,不要將它們用於變量名稱等。

as
def
in
trait

2.數組初始化

在Groovy中,{...}塊保留用於閉包。這意味著您無法使用以下語法創建數組字面量:

// java初始化
int[] array = { 1, 2, 3}
// groovy初始化必須使用方括號
int[] array = [1,2,3]

3.基本類型和包裝類

因為Groovy將Objects用於所有內容,所以它會自動對基本類型進行包裝。因此,它不遵循Java的提升行為優先於自動裝箱。這是一個使用int的例子

int i   // groovy 自動裝箱
m(i)
// Java 會調用這個 基本類型提升優先於自動裝箱
void m(long l) {           
  println "in m(long)"
}
// groovy會調用這個 自動裝箱了已經
void m(Integer i) {        
  println "in m(Integer)"
}

4.==的行為

在Java中==表示基本類型或對象的標識的相等性。
在Groovy中== 如果它們是Comparable,轉換為a.compareTo(b)== 0,否則轉換為a.equals(b)
要檢查一致,有is方法。例如a.is(b)中。

5.方法重載

在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中,=2
assertEquals(2, result);
//在Groovy中:=1
assertEquals(1, result);

這是因為Java將使用靜態信息類型,即o被聲明為Object,而Groovy將在運行時選擇實際調用方法。由於它實際是String的,因此調用String版本。

6. GStrings

由於雙引號字符串文字被解釋為GString值,如果使用Groovy和Java編譯器編譯一個包含美元字符的字符串字面量的類,Groovy可能會因編譯錯誤失敗或產生微妙的不同代碼。
雖然通常情況下,如果API聲明了參數的類型,Groovy將在GString和String之間自動轉換,請註意接受Object參數的Java API,然後檢查實際類型。

7. String and Character 字面量

Groovy中單引號文字用於String,而雙引號結果用於String或GString,具體取決於字面量中是否有插值。

assert ‘c‘.getClass()==String
assert "c".getClass()==String
assert "c${1}".getClass() in GString    // 字面量中有插值 $

只有在分配給char類型的變量時,Groovy才會自動將單字符String轉換為char。當使用char類型的參數調用方法時,我們需要顯式轉換或確保已提前轉換。

    // 提前轉化
    char a=‘a‘
    assert Character.digit(a, 16)==10 : ‘But Groovy does boxing‘
    // 顯式轉化
    assert Character.digit((char) ‘a‘, 16)==10

    try {
      assert Character.digit(‘a‘, 16)==10
      assert false: ‘Need explicit cast‘
    } catch(MissingMethodException e) {
    }

Groovy支持兩種類型的轉換,在轉換為char時,在轉換多字符的串時存在細微差別。 Groovy樣式轉換更寬松,將采用第一個字符,而C樣式轉換將失敗,但異常。

// 單字符的串 轉換一致
assert ((char) "c").class==Character
assert ("c" as char).class==Character

// 多字符的串 轉換規則不一樣
try {
  ((char) ‘cx‘) == ‘c‘
  assert false: ‘will fail - not castable‘
} catch(GroovyCastException e) {
}
assert (‘cx‘ as char) == ‘c‘
// 采用第一個字符
assert ‘cx‘.asType(char) == ‘c‘

8.默認導入

默認情況下導入所有這些包和類,即您不必使用顯式import語句來使用它們:

java.io.*
java.lang.*
java.math.BigDecimal
java.math.BigInteger
java.net.*
java.util.*
groovy.lang.*
groovy.util.*

9.包範圍可見性

在Groovy中,省略字段上的修飾符不會導致像Java一樣的包私有字段:

class Person {
    String name
}

相反,它用於創建屬性,即私有字段,關聯的getter和關聯的setter。 可以通過使用@PackageScope註釋來創建包私有字段:

class Person {
    @PackageScope String name
}

10.ARM塊

Groovy不支持Java 7中的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
   }
}

11.內部類

匿名內部類和嵌套類的實現是Java引領的,但是您不應該排除Java語言規範糾結為什麽不同。這些實現看起來很像我們為groovy.lang.Closure做的,有一些好處和一些差異。例如,訪問私有字段和方法可能會成為一個問題,但另一方面,局部變量不一定是final的。

11.1 靜態內部類

class A {
    // 靜態內部類B
    static class B {}
}

new A.B()

靜態內部類的使用是最受支持的。如果你絕對需要一個內部類,你應該把它變成一個靜態類。

11.2 匿名內部類

import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit

CountDownLatch called = new CountDownLatch(1)

Timer timer = new Timer()
// 匿名內部類 實現了TimerTask接口
timer.schedule(new TimerTask() {
    void run() {
        called.countDown()
    }
}, 0)

assert called.await(10, TimeUnit.SECONDS)

11.3 創建非靜態內部類的實例

public class Y {
    // 非靜態內部類X
    public class X {}
    public X foo() {
        return new X();
    }
    public static X createX(Y y) {
        // 創建非靜態內部類實例
        return y.new X();
    }
}

Groovy不支持y.new X()語法。相反,您必須編寫新的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。基本上相同的規則適用於調用構造函數。
例如,您可能會編寫新的X()而不是新的X(this)。由於這也可能是常規方式,我們尚未找到防止此問題的好方法。

12.Lambdas

Java 8支持lambda和方法引用:

Runnable run = () -> System.out.println("Run");
list.forEach(System.out::println);

Java 8 lambdas可以或多或少地被視為匿名內部類。 Groovy不支持該語法,但有閉包:

// Groovy
Runnable run = { println ‘run‘ }
list.each { println it } // or list.each(this.&println)

12.轉換

Java會自動擴展和縮小轉換
基礎類型 如byte、int、。。

groovy與java語法區別