程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Groovy編程入門攻略

Groovy編程入門攻略

編輯:關於JAVA

Groovy編程入門攻略。本站提示廣大學習愛好者:(Groovy編程入門攻略)文章只能為提供參考,不一定能成為您想要的結果。以下是Groovy編程入門攻略正文


當一個Java開辟人員參加到Groovy的開辟之旅的時刻,他/她常常帶著Java思惟去思慮,並慢慢地進修Groovy,每次進修一個特征,這會讓他漸漸變得更有發明性和寫出更相符說話習氣的Groovy代碼。這篇文章的目標是引誘這些開辟人員去進修根本的Groovy編程作風,進修新的操作技能,新的說話特征,例如閉包等等。這篇文章其實不會具體鋪開描寫,而是給讀者一個入門的指引,並讓讀者在今後的深刻進修打好基本。假如你愛好這篇文章,可以進獻你的一份力氣去豐碩它。

無分號

C / C++ / C# / Java開辟者,常常隨處應用分號。雖然Groovy支撐99%的java語法,有時你只需簡略的把java代碼粘貼到Groovy法式裡,然則卻帶著一年夜堆分號。在Groovy裡,分號是可選的,你可以省略他們,更經常使用的用法是刪除它們。

前往症結字 (Return) 變得可選

在Groovy的世界外面,辦法的法式塊開頭可以不寫'return'症結字而照樣前往值。特別是關於語句不多的辦法和閉包。如許的寫法更幽美更簡練:
 

String toString() {return"a server"}
String toString() {"a server"}

但有些情形卻不那末幽美,例如你應用了變量,並在兩行外面湧現兩次:
 

def props() {
  def m1 = [a:1, b:2]
  m2 = m1.findAll { k, v -> v %2==0}
  m2.c =3
  m2
}

在這個例子外面,或許是在最初一個表達式前面加上一個空行,抑或是顯式地加上'return'症結字會令代碼更有可讀性。

我本身小我習氣,有時刻愛好用return症結字,有時刻又不愛好,這跟小我口胃有關系吧。然則,更多時刻,例如在閉包外面,我更愛好不寫return症結字。所以即便return症結字是可選的,也不會強迫你不克不及應用它,假如你以為它會打破代碼的可讀性。


謹嚴為上,但是當你應用def症結字界說,而並不是用取代詳細某一個類型去界說的辦法,有時刻你會驚異的發明最初一條表達式會作為前往成果而前往。所以更多時刻更推舉應用詳細的類型(例如void或類型)作為前往類型。在我們下面的例子中,假如我們忘卻了把m2放在最初一行並作為前往值,那末最初的一個表達式將是m2.c = 3,如許會招致數值3作為前往值前往,而不是我們等待的成果。

形如if/else語句,try/cath語句異樣可以前往值,由於它們外面都有"最初一個表達式"會被前往。
 

def foo(n) {
  if(n ==1) {
    "Roshan"
  }else{
    "Dawrani"
  }
}
 
assertfoo(1) =="Roshan"
assertfoo(2) =="Dawrani"

Def 和 類型

當我們評論辯論def和類型,我常常會發明一些開辟人員既用'def'又用類型。然則'def'在這裡是過剩的。所以,年夜家要做一個選擇,要不消'def', 要不就用類型。

所以不要寫出以下的代碼:
 

def String name = "Guillaume"

可以寫成
 

String name ="Guillaume"

當我們在Groovy外面應用def,真實的類型是Object(所以你可以向用def界說的變量,賦值任何的對象,而且,當一個辦法是用def作為前往值的時刻,可以以任何對象類型作而前往)。

當一個辦法未聲明變量類型,你可使用def,然則這不是必需的,所以可以省略他,所以可以取代上面的語句:
 

void doSomething(def param1, def param2) { }

推舉:
 

void doSomething(param1, param2) { }

然則,就如我們在文章末尾提到的,我們更推舉為辦法的參數指定類型。如許可以贊助進步代碼的可讀性,也能夠贊助IDE對象使代碼完全,或許應用Groovy的靜態類型檢討或靜態編譯功效。

別的一個def過剩的處所是界說結構函數,應防止應用:
 

class MyClass {
  def MyClass() {}
}

應去失落 結構函數前的'def':
 

classMyClass {
  MyClass() {}
}

默許的Public

默許情形,Groovy會以為類和辦法是界說為'public'的。所以你不須要顯式的聲明public。當須要聲明為非public的時刻,你須要顯式的指定潤飾符。

所以免以下寫法:
 

public class Server {
  public String toString() {return "a server"}
}

推舉應用以下簡練的寫法
 

class Server {
  String toString() {"a server"}
}

你能夠會關懷包規模內的可拜訪性成績。現實上,Groovy許可省略public, 是由於這個包規模外面默許情形下是不支撐public,然則現實上有別的一個Groovy正文語法去完成可拜訪性:
 

class Server {
  @Package ScopeCluster cluster
}

省略圓括號

Groovy許可你在頂級表達式中省略圓括號,例如println語句:
 

println"Hello"
method a, b

比較:
 

println("Hello")
method(a, b)

當辦法的最初一個參數是閉包的時刻,例如應用Groovy的'each'迭代機制,你可以把閉包放在括號以外,乃至省略括號:
 

list.each( { println it } )
list.each(){ println it }
list.each { println it }

平日我們推舉應用下面第三種寫法,它顯得更天然,由於沒有圓括號是何等的過剩!

然則Groovy在某些情形其實不許可你去失落圓括號。就像我之前說的,頂級表達式可以省略,然則嵌套的辦法或許賦值表達式的左邊,你卻不克不及省略:
 

def foo(n) { n }

 

println foo1// 毛病寫法
def m = foo1


類,一級國民

在Groovy外面,.class後綴是不須要的,有點像Java的instanceof。

例如:
 

connection.doPost(BASE_URI +"/modify.hqu", params, ResourcesResponse.class)

上面我們應用GString,並應用第一類國民:
 

connection.doPost("${BASE_URI}/modify.hqu", params, ResourcesResponse)

Getters和Setters

在Groovy的世界裡,getters和setters就是我們常說的"屬性",Groovy供給一個正文語法捷徑給我們去拜訪或給屬性賦值。摒棄java方法的getters/setters,你可使用正文語法:
 

resourceGroup.getResourcePrototype().getName() == SERVER_TYPE_NAME
resourceGroup.resourcePrototype.name == SERVER_TYPE_NAME
 
resourcePrototype.setName("something")
resourcePrototype.name = "something"

當你用Groovy寫beans的時刻,我們平日叫做POGOs(通俗Groovy對象),你不須要本身創立屬性,和getters/setters辦法,而是留給Groovy編譯器來完成。

所以,不再須要如許去寫:
 

class Person {
  private String name
  String getName() {returnname }
  void setName(String name) {this.name = name }
}

而是:
 

class Person {
  String name
}

就如你看到的,一個簡練的"屬性"其實不帶任何的拜訪潤飾符,會讓Groovy編譯器為你主動生成一個公有的屬性和getter和setter辦法。

當你在Java中應用如許一個POGOs對象,getter和setter辦法實際上是存在的,固然跟正常的寫法無異。

固然編譯器可以創立getter/setter辦法,然則當你須要在這辦法外面增長一些特別的邏輯或許跟默許的getter/setter辦法紛歧樣,你可以本身去界說它,編譯器主動會選擇你的邏輯取代默許邏輯。

用定名參數和默許結構器初始化beans

有如許一個bean:
 

class Server {
  String name
  Cluster cluster
}

為防止像上面如許的費事:
 

def server =newServer()
server.name ="Obelix"
server.cluster = aCluster

你可使用定名參數和默許結構器(起首會挪用結構器,然後順次挪用setter辦法):
 

def server =newServer(name:"Obelix", cluster: aCluster)

在統一個bean外面應用with()語法處置反復操作

默許結構器中,定名參數在創立新的實例時是一件非常風趣的工作。然則當你須要更新一個實例時,你能否須要反復地在變量前反復敲打'server'這個前綴呢?謎底能否定的,由於多虧了with()語句,Groovy會主動為你填上:
 

server.name = application.name
server.status = status
server.sessionCount =3
server.start()
server.stop()

比較:
 

server.with {
  name = application.name
  status = status
  sessionCount =3
  start()
  stop()
}

equals 和 ==

Java世界裡,==就相當於Groovy外面的is()辦法,別的Groovy的==就是聰慧的equal()辦法!

當你須要比擬對象的援用的時刻,你應當應用Groovy的==,由於他會幫你避開NullPointerException,而你就不須要關懷操作符的左邊或右邊能否為null。

不該該如許寫:
 

status !=null&& status.equals(ControlConstants.STATUS_COMPLETED)

而是:
 

status == ControlConstants.STATUS_COMPLETED


GStrings ()

我們常常再JAVA外面應用string和變量銜接,並應用年夜量的雙引號,加號,還有\n字符去創立新的一行。而應用插值字符串(在Groovy外面叫做GStrings),可以簡化我們的代碼寫法:
 

throw new Exception("Unable to convert resource: "+ resource)

比較:
 
throw new Exception("Unable to convert resource: ${resource}")
在花括號外面,你可以聽任何的表達式,而不單單是變量。關於簡略的變量,或許變量屬性,你乃至可以丟失落花括號:
 
throw new Exception("Unable to convert resource: $resource")
你乃至可以經由過程閉包正文(${-> resource})對表達式停止延遲盤算。當GString變量強迫轉換為String變量的時刻,它會主動盤算閉包的值,並經由過程挪用toString()辦法作為前往值。例如:
 

int i =3
 
def s1 ="i's value is: ${i}"
def s2 ="i's value is: ${-> i}"
 
i++
 
asserts1 =="i's value is: 3"// 事後盤算,在創立的時刻賦值
asserts2 =="i's value is: 4"// 延遲盤算,應用最新的變量值

在Java外面,字符串聯接是非常的包袱:
 

throw new PluginException("Failed to execute command list-applications:"+
  " The group with name "+
  parameterMap.groupname[0] +
  " is not compatible group of type "+
  SERVER_TYPE_NAME)

你可使用 \ 持續字符 (這不同等於多行文本)

 
throw new PluginException("Failed to execute command list-applications: \
The group with name ${parameterMap.groupname[0]} \
is not compatible group of type ${SERVER_TYPE_NAME}")

或許應用三個雙引號完成多行文本:
 

throw new PluginException("""Failed to execute command list-applications:
  The group with name ${parameterMap.groupname[0]}
  is not compatible group of type ${SERVER_TYPE_NAME)}""")

別的,你也能夠應用.stripIndent()函數完成刪除多行文本外面的左邊過剩空格。


同時請留意Groovy外面單引號和雙引號的差別:單引號平日用來創立Java字符串,不帶任何的插值變量,而雙引號可以創立Java字符串,也能夠用來創立帶插值變量的GStrings。

關於多行字符串,你可使用三個引號:例如在GStrings變量應用三個雙引號,在簡略的String變量中應用三個單引號。

假如你須要寫正則表達式,你必需應用斜槓字符標志:
 

assert"foooo/baaaaar"==~ /fo+\/ba+r/

斜槓標志的利益是,你不須要寫兩個反斜槓去做本義,讓正則表達式更簡練。

最初但並不是不主要,請應用單引號去界說字符常量,應用雙引號界說須要應用插值函數的字符串。


原生的數據構造語法

Groovy對數據構造供給原生語法,例如列表,映照,正則表達式或許一個規模內的數值。請在你的Groovy法式中好好應用它們。

以下是一些例子是應用那些原生數據構造的:
 

def list = [1,4,6,9]
 
// 默許情形下,鍵是字符的,所以沒需要用引號括著它們
// 你可使用with()包括著鍵,例如應用[(狀況變量):狀況名],應用變量或對象作為鍵
def map = [CA:'California', MI:'Michigan']
 
def range =10..20
def pattern = ~/fo*/
 
// 同等於 add()
list <<5
 
// 挪用 contains()
assert4in list
assert5in list
assert15in range
 
// 下標符號
assertlist[1] ==4
 
// 增長鍵值對
map << [WA:'Washington']
// 下標符號
assertmap['CA'] =='California'
// 屬性
assertmap.WA =='Washington'
 
// 應用正則表達式婚配字符串
assert'foo'=~ pattern

 

Grovvy 開辟對象

我們來持續說說數據構造,當你須要迭代聚集,Groovy供給異常豐碩的辦法,裝潢java的焦點數據構造,例如each{}, find{}, findAll{}, every{}, collect{}, inject{}.這些辦法給編程說話增長了些樂趣,同時贊助我們更輕松的設計龐雜的算法。經由過程裝潢器,年夜量的新辦法已運用於java的各類類型,這得得益於說話得的的靜態特征。你可以查找更多的應用在字符串,文件,流,聚集或許其他的辦法:

http://groovy.codehaus.org/groovy-jdk/

switch的力氣

Groovy的switch比C說話家族的更壯大,由於它們平日只吸收根本數據類型和。而Groovy的switch可以接收豐碩的數據類型: 
 

def x =1.23
def result =""
switch(x) {
  case"foo": result ="found foo"
  // lets fall through
  case"bar": result +="bar"
  case[4,5,6,'in List']:
    result ="list"
    break
  case 12..30:
    result ="range"
    break
  case Integer:
    result ="integer"
    break
  case Number:
    result ="number"
    break
  default: result ="default"
}
assert result =="number"

平日情形,應用isCase()辦法可以斷定一個數值能否為年夜小寫。

別號導入 Import aliasing

Java,中當要應用來自兩個分歧包的同名class時,如

java.util.List 和 java.awt.List, 你能導入個中的一個類,而另外一個你就不能不給其有用的重定名了.

還有時刻我們在代碼中常常應用一個名字異常長的類,使得全部代碼變得癡肥不勝.

為了改良這些狀態, Groovy 供給了別號導入的特征:
 

importjava.util.List as juList
importjava.awt.List as aList

 
importjava.awt.WindowConstants as WC   //import的時刻 用 as 設置一個體名
固然也能夠靜態的導入某個辦法:
 

import static pkg.SomeClass.foo
foo()


Groovy 的真值系統

在groovy中一切對象都可以被強迫轉為為一個boolean值,即: null, void 或空值 都 會視為 false, 其他的都視為 true.

所以不要再寫 這類代碼了:if (name != null && name.length > 0) {} 改成: if (name) {}

關於聚集和其他數據類型異樣實用.

是以,你可以在 諸如while(), if(), 三目運算符,Elvis 運算符(上面會講)等等的斷定前提中應用這類簡略的方法.
更強悍的是可以給你的 類 添加 asBoolean() 辦法,從而定制你這個類的真值的。

平安的操尴尬刁難象圖(嵌套的對象) Safe graph navigation

Groovy支撐應用 . 操作符來平安的操作一個對象圖.
Java中假如你對一個對象圖中的某個節點感興致,想檢討其能否為null的時刻,常常會寫出龐雜的if嵌代碼,以下:
 

if(order !=null) { //1
  if(order.getCustomer() !=null) { //2
    if(order.getCustomer().getAddress() !=null) { //3
      System.out.println(order.getCustomer().getAddress());
    }
  }
}

而應用Groovy的平安操作符 ?. 可以講上述代碼簡化為:
 

println order?.customer?.address

太精巧了。

操作連上 每一個?.操作符後面的元素都邑做Null檢討,假如為null則拋出 NullPointerException 而且前往 一個 null值

斷言 Assert

要檢討參數、前往值等,你可使用 assert 語句。

和 Java 的 assert 比較,Groovy 的 assert 無需零丁激活。
 

def check(String name) {
  // name non-null and non-empty according to Groovy Truth
  assertname
  // safe navigation + Groovy Truth to check
  assertname?.size() >3
}

你將留意到 Groovy 的 Power Assert 語句供給更好的輸入,包含每一個子表達式斷言時分歧值的圖形化視圖。

Elvis (埃爾維斯)  ?:  操作符給變量賦默許值

?: 是一個異常便利的給變量 賦 默許值的操作符,他是三目運算符(xx? a:b)的簡寫.
我們常常寫以下三目運算代碼:
 

def result = name !=null? name :"Unknown"//假如name為null時給'Unknown'的默許值,不然用原name的值

感激Groovy的真值系統,null的檢討可簡略直接的經由過程 ‘name'來斷定,null 會被轉成 false.
再深刻一點,既然總得前往'name',那在三目操作運算符中反復輸出name兩次就顯得包袱了,可以將問號和冒號之間輸出的反復變量移除,因而就成了Elvis操作符,以下:
 

def result = name ?:"Unknown"  //假如斷定name為 false 則取 "Unknown",不然 取name之值<span></span>


捕獲任何異常

假如你真的不在意在一個try代碼塊中拋出的異常,groovy中可以簡略的catch一切這些異常,並疏忽其異常類型. 所以今後像這類捕獲異常的代碼:
 

try{
  // ...
}catch(Throwable t) {
  // something bad happens
}

可以寫成捕獲隨意率性異常 ('any' or 'all', 或許其他你以為是"隨意率性"的單詞):
 

try{
  // ...
}catch(any) {
  // something bad happens
}


可選類型 建議

最初我將評論辯論一下什麼時候和如何應用 '可選類型' 這個特征.
Groovy讓你本身來決議是 顯示應用強類型 照樣 應用def 症結字 來聲名你要的器械,那末怎樣決議呢?

我有個相當簡略的經歷軌則:

當你寫的代碼將會被作為公共API給他人應用時,你應該老是應用強類型的聲名。

這將使得: 接口商定加倍明白,防止能夠的毛病類型參數的傳遞,有益於供給更容易讀的文檔,在編纂如:僅你能應用的公有辦法時,強迫類型 會有益於IDE的代碼主動完勝利能,或使IDE更輕易揣摸對象的類型,然後你就可以加倍自若的決議能否應用明白的類型了

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved