Groovy輕鬆入門

  1. 一、什麼是Groovy 
  2.      Groovy 是 JVM 的一個替代語言 — 替代 是指可以用 Groovy 在 Java 平臺上進行 Java 編程,使用方式基本與使用 Java 代碼的方式相同。注意:不是指Groovy替代java,而是指Groovy和java很好的結合編程 
  3.   ● 是一個基於 Java虛擬機的敏捷 動態語言。 
  4.   ● 構建在強大的Java語言之上 並 添加了從Python,Ruby和Smalltalk等語言中學到的 諸多特徵。 
  5.   ● 爲Java開發者提供了 現代最流行的編程語言特性,而且學習成本很低(幾乎爲零)。 
  6.   ● 支持DSL(Domain Specific Languages領域定義語言)和其它簡潔的語法,讓你的代碼變得易於閱讀和維護。 
  7.   ● Groovy擁有處理原生類型,面向對象以及一個Ant DSL,使得創建Shell Scripts變的非常簡單。 
  8.   ● 在開發Web,GUI,數據庫或控制檯程序時 通過 減少框架性代碼 大大提高了開發者的效率。 
  9.   ● 支持單元測試和模擬(對象),可以 簡化測試。 
  10.   ● 無縫集成 所有已經存在的 Java對象和類庫。 
  11.   ● 直接編譯成Java字節碼,這樣可以在任何使用Java的地方 使用Groovy。 
  12.   Groovy 的一個好處是,它的語法與 Java 語言的語法很相似。雖然 Groovy 的語法源於 Smalltalk 和 Ruby 這類語言的理念,但是可以將它想像成 Java 語言的一種更加簡單、表達能力更強的變體。(在這點上,Ruby 與 Groovy 不同,因爲它的語法與 Java 語法差異很大。) 
  13.   許多 Java 開發人員非常喜歡 Groovy 代碼和 Java 代碼的相似性。從學習的角度看,如果知道如何編寫 Java 代碼,那就已經瞭解 Groovy 了。Groovy 和 Java 語言的主要區別是:完成同樣的任務所需的 Groovy 代碼比 Java 代碼更少。(有時候會少很多!)  
  14.  
  15. 二、開發環境 
  16. 1. jdk1.6 
  17. 2. eclipse+groovy plugin(3.7
  18. 打開eclipse,通過 Help->Install New Software,下載並安裝groovy插件。 New一個遠程站點, url可以使用 groovy - http://dist.codehaus.org/groovy/distributions/greclipse/snapshot/e3.7/,選擇安裝groovy插件。 
  19. 三、新建Groovy項目 
  20. 1、新建Groovy項目 
  21. 2、添加Groovy Libraries 
  22. 3、添加Groovy Class,自動生成Main方法,在方法中添加一句代碼“println "Hello World"”,右鍵運行,在控制檯上輸出“Hello World”。 
  23. 四、Groovy語法簡介 
  24. 1、沒有類型的Java 
  25. 作爲動態語言,groovy中所有的變量都是對象(類似.net framework, 所有對象繼承自java.lang.Object),在聲明一個變量時,groovy不要求強制類型聲明,僅僅要求變量名前使用關鍵字def。 
  26. 修改main方法中和代碼: 
  27. def var="hello world" 
  28. println var 
  29. println var.class 
  30. 就可以看到程序最後輸出了var的實際類型爲java.lang.String 
  31. 作爲例外,方法參數和循環變量的不需要def。 
  32. 2、不需要的public 
  33. 你可以把main方法前面的public去掉,實際上groovy中默認的修飾符就是public所以public修飾符根本就不需要寫,這點和java不一樣。 
  34. 3、不需要的語句結束符 
  35. Groovy中沒有語句結束符,當然爲了和java保持一致,也可以使用;號作爲語句結束符。在前面的每一句代碼後面加上;號結束,程序同樣正常運行(爲了接受java程序員的頑固習慣)。 
  36. 4、字符串連接符 
  37. 跟java一樣,如果需要把一個字符串寫在多行裏,可以使用+號連接字符串,代碼可以這樣寫: 
  38. def var = "hello " + 
  39.         "world" + 
  40.         ",groovy" 
  41. 當然更可以這樣寫 
  42. def var = """hello  
  43. world  
  44. groovy!""
  45. 三個"號之間不再需要+號進行連接(不過字符串中的格式都會被保留,包括回車和tab)。 
  46. 5、一切皆對象 
  47. 聽起來像是“衆生平等”的味道,事實上groovy對於對象是什麼類型並不關心,一個變量的類型在運行中隨時可以改變,一切根據需要而定。如果你賦值給它boolean,那麼不管它原來是什麼類型,它接受boolean值之後就會自動把類型轉變爲boolean值。看下面的代碼: 
  48.     def var = "hello " + 
  49.         "world" + 
  50.         ",groovy" 
  51.         println var 
  52.         println var.class 
  53.         var=1001 
  54.         println var 
  55.         println var.class 
  56.         var=false 
  57.         println var 
  58.         println var.class 
  59. 輸出結果是 
  60. hello world,groovy 
  61. class java.lang.String 
  62. 1001 
  63. class java.lang.Integer 
  64. false 
  65. class java.lang.Boolean 
  66. var這個變量在程序運行中,類型在改變。一開始給它賦值String,它的類型就是String,後來給它賦值Integer,它的類型就是Integer,最後給它賦值Boolean,它的類型就是Boolean。 
  67. 6、循環 
  68. 刪除源文件下的所有內容,用一下內容代替 
  69. static void main(String[] args) { 
  70.          
  71.         def var = "hello " + 
  72.         "world" + 
  73.         ",groovy" 
  74.         repeat(var) 
  75.     } 
  76.      
  77.     def static repeat(val) { 
  78.         for(i=0;i<5;i++) { 
  79.             println val 
  80.         } 
  81.     } 
  82. 輸出結果是: 
  83. hello world,groovy 
  84. hello world,groovy 
  85. hello world,groovy 
  86. hello world,groovy 
  87. hello world,groovy 
  88. 注意循環變量i前面沒有def。當然也沒有java中常見的int,但是如果你非要加上int也不會有錯,因爲Groovy 1.1beta2之後開始(不包含1.1beta2),groovy開始支持java經典的for循環寫法。 
  89. 此外,上面的for語句還可以寫成: 
  90.     for(i in 0..<5)  
  91. 這樣的結果是一樣的。 
  92. 7、String和Gstring 
  93. 除了標準的java.lang.String以外,groovy還支持Gstring字符類型。把上面的for循環中的語句換成: 
  94.     println "This is ${i}: ${val}" 
  95. 輸出: 
  96. This is 0: hello world,groovy 
  97. This is 1: hello world,groovy 
  98. This is 2: hello world,groovy 
  99. This is 3: hello world,groovy 
  100. This is 4: hello world,groovy 
  101. 8、範圍 
  102. 在前面的for循環介紹中我們已經使用過的for(i in 0..5) 這樣的用法,其實就是一個範圍。 
  103. 範圍是一系列值。例如“0..4”表示包含整數01234.Groovy還支持排除範圍,“0..<4”表示0123.還可以創建字符範圍:“a..e”相當於a、b、c、d、e。“a..<e”包括小於e的值。 
  104. 9、默認參數值 
  105. 還可以爲方法指定默認參數值。修改repeat方法的定義: 
  106. def static repeat(val, repeatNum=3) { 
  107.         for(i in 0..<repeatNum) { 
  108.             println "This is ${i}: ${val}" 
  109.         } 
  110.     } 
  111. 可以看到,repeat方法增加了一個參數repeatNum(並給了一個默認值3),用於指定循環次數。當我們不指定第二個參數調用repeat方法時,repeatNum參數取默認值。 
  112. 10、集合 
  113. Groovy支持最常見的兩個java集合:java.util.Collection和java.util.Map。前面所說的範圍實際也是一種(java.util.List)。 
  114. (1)Collection 
  115. Groovy中這樣來定義一處collection: 
  116. def collect=["a","b","c"
  117. 除了聲明時往集合中添加元素外,還可以用以下方式向集合中添加元素: 
  118.  
  119. collect.add(1); 
  120. collect<<"Come on" 
  121. collect[collect.size()]=100.0 
  122. Collection使用類似數組下標的方式進行檢索: 
  123. collect[collect.size()-1
  124. collect[5
  125. groovy支持負索引: 
  126.         println collect[-1]  //索引倒數第1個元素 
  127.         println collect[-2]  //索引倒數第2個元素 
  128. Collection支持集合運算: 
  129.         collect=collect+5      //在集合中添加元素5 
  130.         println collect[-1]    //索引倒數第1個元素 
  131.         collect=collect-"a"    //在集合中減去元素a(第1個) 
  132.         println collect[0]     //索引集合中第1個元素(現在是b) 
  133. 同樣地,可以往集合中添加另一個集合或刪除一個集合: 
  134. collect=collect-collect[0..4//把集合中的前5個元素去掉 
  135.         println collect[0]            //現在集合中只有1個元素,即原來最後一個 
  136.         println collect[-1]           //也可以用負索引,證明最後一個元素就是第一個元素 
  137. 2)Map 
  138. Map是“鍵-值”對的集合,在groovy中,鍵不一定是String,可以是任何對象(實際上Groovy中的Map就是java.util.LinkedHashMap)。 
  139. 如此可以定義一個Map: 
  140. def map=['name':'john','age':14,'sex':'boy'
  141. 添加項: 
  142. map=map+['weight':25]     //添加john的體重     
  143. map.put('hight'1.27)    //添加john的身高 
  144. map.father='Keller'       //添加john的父親    
  145. 可以用兩種方式檢索值: 
  146. println map['father']     //通過key索引下標索引 
  147. println map.hight        //通過key作爲成員名索引 
  148. 11、閉包(Closure) 
  149. 閉包是用{符號括起來的代碼塊,它可以被單獨運行或調用,也可以被命名。類似‘匿名類’或內聯函數的概念。 
  150. 閉包中最常見的應用是對集合進行迭代,下面定義了閉包對map進行了迭代: 
  151. map.each ({key,value->println "$key:$value"})  //key,value兩個參數用於接受每個元素 
  152. map.each {println it}                          //it是一個關鍵字,代表map集合的每一個元素 
  153. 除了用於迭代之外,閉包可以單獨定義: 
  154. def say={word-> println "Hi, $word!"
  155. 調用: 
  156.         say("groovy"
  157.         say.call("groovy & java"
  158. 輸出: 
  159. Hi, groovy! 
  160. Hi, groovy & java! 
  161. 看起來,閉包類似於方法,需要定義參數和要執行的語句,它也可以通過名稱被調用。然而閉包對象(不要奇怪,閉包也是對象)可以作爲參數傳遞(比如前面的閉包作爲參數傳遞給map的each方法)。而在java中,要做到這一點並容易(也許c++的函數指針可以,但不要忘記java中沒有指針)。其次,閉包也可以不命名(作爲代價,不能在定義閉包時執行一次),而方法不可以。 
  162. 12、類 
  163. Groovy類的java類一樣,你完全可以用標準java bean的語法定義一個Groovy類。但作爲另一種語言,我們可以使用更Groovy的方式定義的使用類,這樣的好處是,你可以少寫一半以上的javabean代碼。 
  164. 1)不需public修飾符 
  165. 如前面所言,Groovy的默認訪問修飾符就是public,如果你的Groovy類成員需要public修飾,則你根本不用寫它。 
  166. 2)不需要類型說明 
  167. 同樣前面也說過,Groovy也不關心變量和方法參數的具體類型。 
  168. 3)不需要getter/setter方法 
  169. 不要奇怪,在很多ide(如eclipse)早就可以爲程序員自動產生getter/setter方法了。在Groovy中,則徹底不需要getter/setter方法--所有類成員(如果是默認的public)根本不用通過getter/setter方法引用它們(當然,如果你一定要通過getter/setter方法訪問成員屬性,Groovy也提供了它們)。 
  170. 4)不需要構造函數 
  171. 不再需要程序員聲明任何構造函數,因爲實際上只需要兩個構造函數(1個不帶參數的默認構造函數,1個只帶一個map參數的構造函數--由於是map類型,通過這個參數你可以構造對象時任意初始化它的成員變量)。 
  172. 5)不需要return 
  173. Groovy中,方法不需要return來返回值嗎?這個似乎很難理解,看後面的代碼吧,因此,Groovy風格的類是這樣的 
  174. 6)不需要() 
  175. Groovy中方法調用 可以省略()(構造函數除外),也就是說下面兩名是等同的: 
  176.         def person1 = new Person() 
  177.         person1.setName "john" 
  178.         person1.setAge(25
  179. 下面看一個完整類定義的例子: 
  180. class Person { 
  181.     def name 
  182.     def age 
  183.     String toString() { //注意方法是String,因爲我們需要覆蓋的方法爲String類型 
  184.         "$name, $age" 
  185.     } 
  186. 如果你使用javabean風格來做同樣的事,起碼代碼量要增加1倍以上。 
  187. 我們可以使用默認構造方法實例化Person類: 
  188.         def person1 = new Person() 
  189.         person1.setName "john" 
  190.         person1.setAge(25
  191. 也可以用Groovy的風格做同樣的事: 
  192. def person2=new Person(['name':'john','age':25])     
  193. println person2 
  194. 這樣需要注意我們覆蓋了Object的toString方法,因爲我們想通過println person1這樣的方法簡單地打印對象的屬性值。 
  195. 然而toString方法中並沒有return一個String,但不用擔心,Groovy默返回方法的最後一行的值。 
  196. 13、?運算符 
  197. 在java中,有時候爲了避免出現空指針異常,我們通常需要這樣的技巧: 
  198. if(rs!=null) { 
  199.             rs.next() 
  200.             ...... 
  201.         } 
  202. 在Groovy中,可以使用?操作符達到同樣的目的: 
  203. rs?.next() 
  204. ?在這裏是一個條件運算符,如果?前面的對象非null,執行後面的方法,否則什麼也不做。 
  205. 14、可變參數 
  206. 等同於java5中的變長參數。首先我們定義一個變長參數的方法sum: 
  207.     int sum(int... var) { 
  208.         def total=0 
  209.         for(i in var) { 
  210.             total+=1 
  211.         } 
  212.             return total 
  213.     } 
  214. 我們可以調用sum時使用任意個的參數(1個,2個,3個……): 
  215.         println sum(1)       
  216.         println sum(1,2
  217.         println sum(1,2,3
  218. 15、枚舉 
  219. 定義一個enum: 
  220.         def today=Day.SATURDAY 
  221.         switch(today) { 
  222.             //Saturday or Sunday 
  223.             case [Day.SATURDAY, Day.SUNDAY]: 
  224.             println "Weekends are cool" 
  225.             break
  226.             case Day.MONDAY..Day.FRIDAY: 
  227.             println "Boring work day" 
  228.             break
  229.             default
  230.             println "Are you sure this is a valid day?" 
  231.         } 
  232. 注意,switchcase中可以使用任何對象,尤其是可以在case中使用List和範圍,從而使分支滿足多個條件。 
  233. 同java5一樣,Groovy支持帶構造器。屬性的方法的enum
  234.  
  235. enum Planet { 
  236.     MERCURY(3.303e+23,2.4397e6), 
  237.     VENUS(4.869e+24,6.0518e6), 
  238.     EARTH(5.976e+24,6.37814e6), 
  239.     MARS(6.421e+23,3.3972e6), 
  240.     JUPITER(1.9e+27,7.1492e7), 
  241.     SATURN(5.688e+26,6.0268e7), 
  242.     URANUS(8.686e+25,2.5559e7), 
  243.     NEPTUNE(1.024e+26,2.4746e7) 
  244.     double mass 
  245.     double radius 
  246.     Planet(double mass, double radius) { 
  247.         this.mass=mass 
  248.         this.radius=radius 
  249.     } 
  250.     void printMe(){ 
  251.         println :"${name()} has a mass of ${mass} and a radius of ${radius}" 
  252.     } 
  253. Planet.EARTH.printMe() 
  254. 16、Elvis運算符 
  255. 這是三目運算符“?:”的簡單形式,三目運算符通常以這種形式初戀: 
  256. String displayName=name!=null?name:"Unknown"
  257. 在Groovy中,也可以簡化爲(因爲null在Groovy中可以轉化爲布爾值false): 
  258. String displayName=name?name:"Unknown"
  259. 基於“不重複”的原則,可以是用elvis操作符再次簡化爲: 
  260. String displayName=name?:"Unknown"
  261. 17、動態性 
  262. Groovy所有的對象都有一個元素metaClass,我們可以通過metaClass屬性訪問該元類。通過元類,可以爲這個對象增加方法(在java中不可想象!)見下面的代碼,msg是一個String,通過元類,我們爲msg增加了一個String類中沒有的方法up: 
  263. def msg="Hello!" 
  264.         println msg 
  265.         println msg.metaClass  
  266.         String.metaClass.up={delegate.toUpperCase()} 
  267.         println msg.up() 
  268. 通過元類,我們還可以檢索對象所擁有的方法和屬性(就是反射): 
  269. msg.metaClass.metaMethods.each {println it.name} 
  270.         msg.metaClass.properties.each { println it.name} 
  271. 甚至我們可以看到我們剛纔添加的up方法。 
  272. 我們可以通過元類判斷有沒有一個叫up的方法,然後再調用它: 
  273. if (msg.metaClass.respondsTo(msg, 'up')) { 
  274.             println msg.up() 
  275.         } 
  276. 當然,也可以推斷它有沒有一個叫bytes的屬性: 
  277.         if(msg.metaClass.hasProperty(msg, 'bytes')) { 
  278.             println msg.bytes.encodeBase64() 
  279.         } 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章