天天看點

《Groovy官方文檔》1.3 Groovy和Java比較

原文位址     譯文位址  譯者:jackwang

groovy語言一直在努力親近java開發人員。在設計groovy語言的時候,我們遵循最小标新立異原則,努力讓那些java開發背景的開發者容易上手并學會。下面我們列舉groovy和java的一些主要差別。

下面的包和類是預設導入的,也就是說不必精确使用 import 語句來導入它們:

java.io.*

java.lang.*

java.math.bigdecimal

java.math.biginteger

java.net.*

java.util.*

groovy.lang.*

groovy.util.*

在groovy裡,方法的調用是在運作時動态決定。這一特性叫做運作時分發(runtime dispatch)或動态方法(multi-methods)。也就是說方法的最後調用是根據傳入參數在運作時的類型所決定。在java裡,這一點是不一樣的:在編譯時就決定了方法的參數類型。

下面的代碼,我們采用java風格,在groovy和java都可以編譯通過,但是運作結果不一樣:

在java裡,結果是

但是groovy裡,結果是

assertequals(1, result);

原因是java使用的是靜态聲明的類型資訊,這裡o被聲明為object,但是groovy是在運作時決定,當方法最終被調用時,因為這裡o實際是一個字元串,是以最終string版本的方法被調用。

譯者注:譯者之前也沒有接觸過groovy語言,空閑時間也是有限的(姑且讓我找這個借口吧,雖然這個借口很牽強,對待知識本來應該以一種嚴謹,求真的态度)是以這裡有些專有名字可能翻譯不是很準确,比如對multi-methods的翻譯。譯者也不确定是否準确,是以附帶了原文單詞,請讀者自行根據示例代碼和上下文意思了解。如果找到準确的中文翻譯懇請評論留言,以待修正。

在groovy,{…}已經被用作閉包,也就是說你不能使用下面的文法建立數組(譯者注:java可以,并且很常用)

你應該這樣聲明并初始化一個數組

在groovy裡,省略字段的修飾符不會像java一樣使其成為包私有屬性(package-private field)

這裡,我們建立了一個屬性,它是私有的,而且自動關聯了getter和setter方法。如果我們要建立一個包私有屬性,可以添加@packagescope注解來實作:

arm(automatic resource management 自動資源管理)塊從java7開始支援,但是groovy不支援。相應地,groovy依賴于閉包來實作類似的功能。示例:

在groovy裡可以寫成:

或者也可以寫成跟java類似風格:

groovy遵循了java的匿名内部類以及嵌套内的特點。但是它并沒有完全依照java語言規範,是以在使用前應該記住它們是有差別的。groovy的實作和groovy.lang.clouser類的風格有些類似,但也有不同點。比如在通路私有字段和方法以及局部變量沒有final等。

這是一個靜态内部類的例子:

使用靜态内部類是一個非常好的實踐,如果你一定要使用内部類,建議優先考慮靜态内部類。

在java裡,你可以這樣寫:

groovy不支援y.new x()文法,但你可以寫成new x(y),像下面的代碼:

特别注意,groovy支援調用無參方法傳入一個參數。那個參數的值将會是null。這個特性對于調用構造函數同樣适用。可能會有人寫new x(this)而不是new x(),這是不合法的。雖然我們還沒有找到辦法避免使用者這樣寫。

java 8 支援拉姆達表達式和方法引用

java8的拉姆達表達式或多或少被認為是匿名内部類。groovy不支援這樣的文法,但是可以使用閉包代替:

使用雙引号修飾的字元串被解釋為gstring值。如果一個字元串裡含有美元符号在groovy和java的編譯器裡将會産生編譯錯誤。

當然,groovy會自動在gstring和string之間進行類型轉換,就像java可以接受一個object參數然後檢查其實際類型一樣。

在groovy裡,使用單引号修飾的被當成string類型,使用雙引号修飾的可以當成gstring類型或string類型。取決于字面常量。

如果聲明是char類型,groovy會自動将單個字元從string類型轉換為char類型。如果被調用的方法聲明的參數類型是char,我們需要強制類型轉換為char類型。

groovy支援兩種風格的類型轉換,在轉換成char類型的時候,當個字元和多個字元轉換有些不一樣。對于多個字元轉換成char類型,groovy會選擇第一個字元,這一點不像c語言,會直接失敗。

在java裡,==意味着基本類型相等或對象類型相等。在groovy裡,==會轉換成a.compareto(b)==0,如果他們是comparable,就是使用a.equals(b),否則檢查基本類型,也就是is,比如a.is(b)

groovy比java有更多的關鍵字,請不要把它們當變量名使用

in

trait