日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Groovy 使用完全解析

發布時間:2024/9/30 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Groovy 使用完全解析 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉載請標明出處:http://blog.csdn.net/zhaoyanjun6/article/details/70313790
本文出自【趙彥軍的博客】

文章目錄

    • 概念
    • Groovy 配置環境變量
    • 開發工具 IntelliJ IDEA
    • Groovy 語法
      • 基本語法
      • 定義變量
      • 定義函數
      • 斷言 assert
      • 循環 for
      • 循環 time
      • 三目運算符
      • 捕獲異常
      • switch
      • 判斷是否為真
      • asType
    • Groovy 數據類型
      • **Java 基本類型**
      • **Groovy 容器**
    • 閉包
    • Java 屬性
    • 再識 Groovy
      • Script 類
    • 腳本變量的作用域
    • JSON 操作
      • 對象轉json 、 json 轉對象
      • 集合對象轉json 、json 轉集合對象
    • I/O 操作
      • 文本文件讀
      • 文本文件寫
      • 文件夾操作
      • 深度遍歷文件
      • InputStream
    • xml 解析
      • 實例1 解析簡單xml
      • 實例2 解析復雜 xml

概念

Groovy是一種動態語言,它和Java類似(算是Java的升級版,但是又具備腳本語言的特點),都在Java虛擬機中運行。當運行Groovy腳本時它會先被編譯成Java類字節碼,然后通過JVM虛擬機執行這個Java字節碼類。

Groovy 配置環境變量

  • 在 Groovy 官網下載壓縮包 http://www.groovy-lang.org/download.html

  • 然后解壓到本地,如圖所示:

  • 在 Path 環境變量中添加 Groovy 的bin 目錄路徑,比如:

D:\soft\apache-groovy-sdk-2.4.10\groovy-2.4.10\bin

如圖所示:

  • 用 CMD 打開命令行,執行:groovy -version , 如果看到如下提示,就代表配置成功了。

Groovy Version: 2.4.10 JVM: 1.8.0_112 Vendor: Oracle Corporation OS: Windows 10

如圖所示:

開發工具 IntelliJ IDEA

groovy 的開發工具是 IntelliJ IDEA
下載地址: https://www.jetbrains.com/idea/

安裝完成后,新建項目 ,項目類型選擇 Groovy ,然后填寫 JDK 、Groovy 的安裝目錄

新建的項目 Groovy 如下圖所示:

在 src 目錄下,新建包名 groovy , 并且創建 groovy 源文件 Test.groovy,如下圖所示:

現在我們在 Test.groovy 中輸出一句 helloword ,代碼如下:

package groovyprintln( "hello world")

運行 Test.groovy 文件 ,如下圖所示:

Groovy 語法

基本語法

1、Groovy注釋標記和Java一樣,支持 //或者/**/

2、Groovy語句可以不用分號結尾。Groovy為了盡量減少代碼的輸入,確實煞費苦心

3、單引號

單引號’’ 中的內容嚴格對應Java中的String,不對 $ 符號進行轉義

def s1 = 'i am 100 $ dolloar' println( s1 )

運行結果:

i am 100 $ dolloar

4、雙引號

雙引號""的內容則和腳本語言的處理有點像,如果字符中有號的話,則它會號的話,則它會表達式先求值。

def x = 100 def s1 = "i am $x dolloar"println( s1 )

運行結果:

i am 100 dolloar

5、三引號

三個引號’’‘xxx’’'中的字符串支持隨意換行 比如

def s1 = ''' x y z f '''println(s1)

運行結果:

x y z f

定義變量

Groovy中支持動態類型,即定義變量的時候可以不指定其類型。Groovy中,變量定義可以使用關鍵字def。注意,雖然def不是必須的,但是為了代碼清晰,建議還是使用def關鍵字

  • 定義一個變量
def a = 1 //定義一個整形def b = "字符串" //定義一個字符串def double c = 1.0 //定義一個 double 類型,也可以指定變量類型

定義函數

無返回類型的函數定義,必須使用def關鍵字 ,最后一行代碼的執行結果就是本函數的返回值

//無參函數 def fun1(){}//有參函數 , 無需指定參數類型 def fun2( def1 , def2 ){}

如果指定了函數返回類型,則可不必加def關鍵字來定義函數

String fun3(){return "返回值" }

其實,所謂的無返回類型的函數,我估計內部都是按返回Object類型來處理的。畢竟,Groovy 是基于Java 的,而且最終會轉成 Java Code 運行在 JVM 上 .

Groovy的函數里,可以不使用return xxx 來設置 xxx 為函數返回值。如果不使用 return 語句的話,則函數里最后一句代碼的執行結果被設置成返回值。

def getSomething(){ "getSomething return value" //如果這是最后一行代碼,則返回類型為String 1000 //如果這是最后一行代碼,則返回類型為Integer }

除了每行代碼不用加分號外,Groovy中函數調用的時候還可以不加括號

例子1:

def s1 = "123"println(s1)//或者println s1

例子2:

println(fun1())println fun1()def fun1(){"你好" }

效果:

你好 你好

斷言 assert

  • 斷言變量為空
def s1 = nullassert s1

效果如下:

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-YixwoPo6-1609157395410)(https://img-blog.csdn.net/20170915162248368?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhhb3lhbmp1bjY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)]

  • 斷言變量的長度
def s2 = "abc"assert s2.size()>3

效果如下:

如果斷言發生,斷言后面的代碼無法執行

循環 for

  • 方式一
for (i = 0; i < 5 ; i++) {println("測試") }

1、運行結果: 輸出5個測試
2、groovy 語法中,注意 i 前面不用指定 int 類型。

  • 方式二
for (i in 0..5){println("hello world") }

這種方式也是一種循環,只不過他輸出的是 6 個 hello world , 如果想要輸出5個,有3中方式。

第一種方法

for (i in 0..<5){println("hello world") }

第二種方法

for (i in 0..4){println("hello world") }

第三種方法

for (i in 1..5){println("hello world") }

循環 time

times表示從0開始循環到4結束

4.times {println it }

結果:

0 1 2 3

三目運算符

Java 語法

def name def result = name != null ? name : "abc" println(result)

groovy 語法

def name = 'd' def result = name?: "abc"

捕獲異常

捕獲所有的 Exception ,有兩種寫法

//第一種寫法,Java 寫法 try {println 5 / 0 } catch (Exception e) {}//第二種寫法,Groovy 寫法 try {println 5 / 0 } catch (anything) {}

這里的any并不包括Throwable,如果你真想捕獲everything,你必須明確的標明你想捕獲Throwable

switch

age = 36 def rateswitch (age) {case 10..26:rate = 0.05breakcase 27..36:rate = 0.06breakcase 37..46:rate = 0.07breakdefault:throw new IllegalArgumentException() }println( rate)

判斷是否為真

Person person//Java 寫法 if (person!= null){if (person.Data!=null){println person.Data.name} }//Groovy println person?.Data?.name

asType

asType 就是數據類型轉換

//String 轉成 int def s2 = s1 as int//String 轉成 int def s3 = s1.asType(Integer)

Groovy 數據類型

Groovy中的數據類型主要分2種

  • 一個是Java中的基本數據類型。

  • 另外一個是Groovy中的容器類。

  • 最后一個非常重要的是閉包。

Java 基本類型

def boolean s1 = truedef int s2 = 100def String s3 = "hello world"if (s1) {println("hello world") }

Groovy 容器

List:鏈表,其底層對應Java中的List接口,一般用ArrayList作為真正的實現類。
Map:鍵-值表,其底層對應Java中的LinkedHashMap。
Range:范圍,它其實是List的一種拓展。

  • List
//變量定義:List變量由[]定義,其元素可以是任何對象 def aList = [5,'string',false]println(aList)println aList[0] //獲取第1個數據println aList[1] //獲取第2個數據println aList[2] //獲取第3個數據println aList[3] //獲取第4個數據println( "集合長度:" + aList.size())//賦值aList[10] = 100 //給第10個值賦值aList<<10 //在 aList 里面添加數據println aListprintln "集合長度:" + aList.size()

效果如下:

[5, string, false] 5 string false null 集合長度:3 [5, string, false, null, null, null, null, null, null, null, 100] 集合長度:11
  • map
def map = [key1: "value1", key2: "value2", key3: "value3"]println map //[key1:value1, key2:value2, key3:value3]println("數據長度:" + map.size()) //數據長度:3println(map.keySet()) //[key1, key2, key3]println(map.values()) //[value1, value2, value3]println("key1的值:" + map.key1) //key1的值:value1println("key1的值:" + map.get("key1")) //key1的值:value1//賦值 map.put("key4", "value4")Iterator it = map.iterator() while (it.hasNext()) {println "遍歷map: " + it.next() }//遍歷map: key1=value1 //遍歷map: key2=value2 //遍歷map: key3=value3 //遍歷map: key4=value4map.containsKey("key1") //判斷map是否包含某個keymap.containsValue("values1") //判斷map是否包含某個valuesmap.clear() //清除map里面的內容Set set = map.keySet(); //把 map 的key值轉換為 set
  • range

Range 是 Groovy 對 List 的一種拓展

def range = 1..5println(range) //[1, 2, 3, 4, 5]range.size() //長度range.iterator() //迭代器def s1 = range.get(1) //獲取標號為1的元素range.contains( 5) //是否包含元素5range.last() //最后一個元素range.remove(1) //移除標號為1的元素range.clear() //清空列表

例子2:

def range = 1..5println(range) //[1, 2, 3, 4, 5]println("第一個數據: "+range.from) //第一個數據 //第一個數據: 1println("最后一個數據: "+range.to) //最后一個數據 //最后一個數據: 5

閉包

閉包,英文叫Closure,是Groovy中非常重要的一個數據類型或者說一種概念了。閉包,是一種數據類型,它代表了一段可執行的代碼。

def aClosure = {//閉包是一段代碼,所以需要用花括號括起來.. String param1, int param2 -> //這個箭頭很關鍵。箭頭前面是參數定義,箭頭后面是代碼 println"this is code" //這是代碼,最后一句是返回值, //也可以使用return,和Groovy中普通函數一樣 }

簡而言之,Closure的定義格式是:

def xxx = {paramters -> code} //或者 def xxx = {無參數,純code}

說實話,從C/C++語言的角度看,閉包和函數指針很像。閉包定義好后,要調用它的方法就是:
閉包對象.call(參數)
或者更像函數指針調用的方法:
閉包對象(參數)
比如:

aClosure.call("this is string",100) //或者 aClosure("this is string", 100)

實例演練,源碼如下

def fun1 = {p1 ->def s = "我是一個閉包," + p1 }println(fun1.call()) //閉包 調用方式1println(fun1.call("我是一個參數")) //閉包 調用方式2println(fun1("我是一個參數2"))

運行結果如下:

我是一個閉包,null 我是一個閉包,我是一個參數 我是一個閉包,我是一個參數2

閉包沒定義參數的話,則隱含有一個參數,這個參數名字叫it,和this的作用類似。it代表閉包的參數。

def fun2 = {it-> "dsdsd" }println( fun2.call())

如果在閉包定義時,采用下面這種寫法,則表示閉包沒有參數!

def fun3 = {-> "dsdsd" }println( fun3.call())

如果調用 fun3 的時候傳遞參數就會報錯,比如

fun3.call("d") //執行這個方法的時候就會報錯

省略圓括號

def list = [1,2,3] //定義一個List//調用它的each,這段代碼的格式看不懂了吧?each是個函數,圓括號去哪了?list.each {println(it) }//結果/*** 1* 2* 3*/

each函數調用的圓括號不見了!原來,Groovy中,當函數的最后一個參數是閉包的話,可以省略圓括號。比如

def fun(int a1,String b1, Closure closure){ //dosomething closure() //調用閉包 }

那么調用的時候,就可以免括號!

fun (4, "test", { println"i am in closure" })

注意,這個特點非常關鍵,因為以后在Gradle中經常會出現這樣的代碼:

task hello{doLast{println("hello world")} }

省略圓括號雖然使得代碼簡潔,看起來更像腳本語言

Java 屬性

Groovy中可以像Java那樣寫package,然后寫類。比如我們在 Person.groovy 文件中編寫Java 代碼,如下所示:

然后我們新建 Test.groovy 類,寫測試工程,如下所:

運行結果如下所示:

Person{name='zhaoyanjun', age=20}

當然,如果不聲明public/private等訪問權限的話,Groovy中類及其變量默認都是public的.

再識 Groovy

Java中,我們最熟悉的是類。但是我們在Java的一個源碼文件中,不能不寫class(interface或者其他…),而Groovy可以像寫腳本一樣,把要做的事情都寫在xxx.groovy中,而且可以通過groovy xxx.groovy直接執行這個腳本。這到底是怎么搞的?

既然是基于Java的,Groovy會先把xxx.groovy中的內容轉換成一個Java類。

在運行完 Test.groovy 后,發現會產生一個 out 目錄,在這個目錄里面可以看到 Person.groovy 、Test.groovy 被轉換成了 .class 文件,如下圖所示:

  • 編譯完成后,.groovy 文件都被轉換成了 .class 文件,每個 .class 文件都默認有靜態 main 方法。每一個腳本都會生成一個static main函數。這樣,當我們groovytest.groovy的時候,其實就是用java去執行這個main 函數。

  • 腳本中的所有代碼都會放到run函數中。比如,println ‘Groovy world’,這句代碼實際上是包含在run函數里的。

  • Test 繼承 Script 類。

Script 類

在 groovy 的庫文件中,可以看到 Script 類是一個抽象類,繼承 GroovyObjectSupport 類,如下所示

腳本變量的作用域

在 Test.groovy 里面定義變量 s1 , 方法 fun1 , 同時在 fun1 方法中輸出 s1 , 代碼如下:

一運行就報錯,錯誤如下

通過 out 目錄,查看 Test.class 類如下:

可以看到在 s1 變量定義在 run 方法中,相當于局部變量,fun1 方法自然無法訪問 s1 .

解決方法也很簡單 ,就是把 s1 的 def 去掉,代碼如下:

通過 out 目錄,查看 Test.class 類如下:

上圖中 s1 也沒有被定義成 Test 的成員函數,而是在 run 的執行過程中,將 s1 作為一個屬性添加到 Test 實例對象中了。然后在print s1 中,先獲取這個屬性。但是從反編譯的實際上看,s1 并沒有成為 Test.class 的成員變量,其他腳本卻無法訪問 s1 變量 。

怎樣使 s1 徹徹底底變成 Test 的成員變量?

答案也很簡單在 s1 前面加上 @Field 字段

@Field s1 = "123" //s1 徹徹底底變成 Test 的成員變量

反編譯效果如下:

JSON 操作

JsonOutput 類把對象轉換成 json字符串。

JsonSlurper 類把 json 字符串轉換成對象

定義 Person 實體類

public class Person {String name;int age; }

對象轉json 、 json 轉對象

Person person = new Person(); person.name = "zhaoyanjun" person.age = 27//把對象轉換為 json 字符串 def json =JsonOutput.toJson(person)println(json)JsonSlurper jsonSlurper = new JsonSlurper()//把字符串轉換為對象 Person person1 = jsonSlurper.parseText(json)println( person1.name )

運行效果如下圖:

{"age":27,"name":"zhaoyanjun"} zhaoyanjun

集合對象轉json 、json 轉集合對象

Person person = new Person(); person.name = "zhaoyanjun" person.age = 27Person person1 = new Person(); person1.name = "zhaoyanjun2" person1.age = 28def list = [person,person1]//把集合對象轉換為 json 字符串 def jsonArray =JsonOutput.toJson(list)println(jsonArray)JsonSlurper jsonSlurper = new JsonSlurper()//把字符串轉換為集合對象 List<Person> list2 = jsonSlurper.parseText(jsonArray)println( list2.get(1).name )

運行結果為:

[{"age":27,"name":"zhaoyanjun"},{"age":28,"name":"zhaoyanjun2"}] zhaoyanjun2

I/O 操作

Groovy的 I/O 操作是在原有Java I/O操作上進行了更為簡單方便的封裝,并且使用Closure來簡化代碼編寫。雖然比Java看起來簡單,但要理解起來其實比較難。

文本文件讀

在電腦上新建一個文本文件 test.txt , 內容如下:

今天是星期五 天氣很好 明天就要放假了

下面用 groovy 讀取里面的文本

def filePath = "C:/Users/T/Desktop/test.txt" def file = new File(filePath) ;file.eachLine {println it }

你沒有看錯,就是這么簡單,groovy 的文件讀取操作簡單到令人發指。但是這不夠,還有跟令人發指的操作,比如:

def filePath = "C:/Users/T/Desktop/test.txt" def file = new File(filePath) ;println file.text //輸出文本

看到這里,發現 Groovy 操作文件比 Java 簡單了 100 倍,蒼天啊!

更多用法

  • 指定編碼格式
def filePath = "C:/Users/T/Desktop/test.txt" def file = new File(filePath);//指定編碼格式為 utf-8 file.eachLine("utf-8") {println it //讀取文本 }
  • 把小寫轉成大寫
def filePath = "C:/Users/T/Desktop/test.txt" def file = new File(filePath);file.eachLine {println( it.toUpperCase() ) }

文本文件寫

  • 方式1
def filePath = "C:/Users/T/Desktop/test.txt" def file = new File(filePath);file.withPrintWriter {it.println("測試")it.println("hello world") }
  • 方式2
def filePath = "C:/Users/T/Desktop/test.txt" def file = new File(filePath);def out = file.newPrintWriter(); out.println("測試") out.println("hello world") out.flush() out.close()

效果如下:

文件夾操作

  • 遍歷文件夾中的文件、文件
def filePath = "C:/Users/T/Desktop/123" def file = new File(filePath);//遍歷 123 文件夾中文件夾 file.eachDir {println "文件夾:"+it.name }//遍歷 123 文件夾中的文件 file.eachFile {println "文件:"+ it.name }

效果如下:

文件夾:1 文件夾:2 文件夾:3 文件:1 文件:2 文件:3 文件:4.txt

深度遍歷文件

def filePath = "e:/" def file = new File(filePath);//深度遍歷目錄,也就是遍歷目錄中的目錄 file.eachDirRecurse {println it.name }//深度遍歷文件,包括目錄和文件 file.eachFileRecurse {println it.path }

InputStream

def filePath = "C:/Users/T/Desktop/test.txt" def file = new File(filePath) ;def ism = file.newInputStream() //操作ism,最后記得關掉ism.close

使用閉包操作 inputStream,以后在Gradle里會常看到這種搞法

def filePath = "C:/Users/T/Desktop/test.txt" def file = new File(filePath) ;file.withInputStream {ism->// 操作ism. 不用close。Groovy會自動替你close ism.eachLine {println it //讀取文本} }

確實夠簡單,令人發指。我當年死活也沒找到withInputStream是個啥意思。所以,請各位開發者牢記Groovy I/O操作相關類的SDK地址:

  • java.io.File: http://docs.groovy-lang.org/latest/html/groovy-jdk/java/io/File.html
  • java.io.InputStream: http://docs.groovy-lang.org/latest/html/groovy-jdk/java/io/InputStream.html
  • java.io.OutputStream: http://docs.groovy-lang.org/latest/html/groovy-jdk/java/io/OutputStream.html
  • java.io.Reader: http://docs.groovy-lang.org/latest/html/groovy-jdk/java/io/Reader.html
  • java.io.Writer: http://docs.groovy-lang.org/latest/html/groovy-jdk/java/io/Writer.html
  • java.nio.file.Path: http://docs.groovy-lang.org/latest/html/groovy-jdk/java/nio/file/Path.html

xml 解析

在java中解析xml是非常繁瑣的,通常需要用10行代碼去解析5行的xml文件,非常不經濟。在groovy 中解析xml 就很方便了。

實例1 解析簡單xml

比如下面一段xml

<?xml version="1.0"?><langs type="current"> <language>Java</language> <language>Groovy</language> <language>JavaScript</language> </langs>

groovy 解析如下:

//獲取 xml 文件的 langs 節點 def langs = new XmlParser().parse("C:/Users/T/Desktop/test.xml")//獲取type 字段的值 def type = langs.attribute("type")println typelangs.language.each{println it.text() }

結果如下:

current Java Groovy JavaScript

實例2 解析復雜 xml

xml 如下圖所示:

<?xml version="1.0" encoding="UTF-8"?> <metadata><groupId>com.yiba.sdk</groupId> <artifactId>weshareWiFiSDk</artifactId> <version>2.3.3</version><versioning> <latest>2.3.3</latest><versions><version>2.2.7</version><version>2.3.0</version><version>2.3.1</version><version>2.3.2</version><version>2.3.3</version></versions> </versioning></metadata>

解析代碼如下:

//獲取metadata節點 def metadata = new XmlParser().parse("C:/Users/T/Desktop/test1.xml")//獲取metadata下面的 groupId 屬性值 def groupId = metadata.groupId.text()//獲取metadata下面的 artifactId 屬性值 def artifactId = metadata.artifactId.text()//獲取metadata下面的 version 屬性值 def version = metadata.version.text()println groupId + " " + artifactId + " " + version//獲取metadata下面的 versioning 節點 def versioning = metadata.versioning//獲取versioning 下面的 latest 屬性值 println versioning.latest.text()//獲取versioning 下面的 versions 節點 def versions = versioning.versions versions.version.each{//遍歷 versions 下面的version 值println "version" + it.text() }

結果如下:

com.yiba.sdk weshareWiFiSDk 2.3.3 2.3.3 version2.2.7 version2.3.0 version2.3.1 version2.3.2 version2.3.3

個人微信號:zhaoyanjun125 , 歡迎關注
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-DbdhcgIu-1609157395419)(http://o7rvuansr.bkt.clouddn.com/weixin200.jpg)]

總結

以上是生活随笔為你收集整理的Groovy 使用完全解析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。