| ページ一覧 | ブログ | twitter |  書式 | 書式(表) |

MyMemoWiki

「Groovy」の版間の差分

提供: MyMemoWiki
ナビゲーションに移動 検索に移動
(ページの作成:「==Groovy== [Gradle] {{amazon|4774147273}} *この本を参考にまとめる ==概要== *JVM上で動作する *Javaと直接的な連携が特徴 *動的言…」)
 
 
(同じ利用者による、間の2版が非表示)
1行目: 1行目:
==Groovy==
+
==[[Groovy]]==
[Gradle]
+
[[Gradle]] |
 
{{amazon|4774147273}}
 
{{amazon|4774147273}}
  
6行目: 6行目:
 
==概要==
 
==概要==
 
*JVM上で動作する  
 
*JVM上で動作する  
*Javaと直接的な連携が特徴
+
*[[Java]]と直接的な連携が特徴
*動的言語であり直接スクリプトを実行できる
+
*動的[[言語]]であり直接スクリプトを実行できる
*バイトコードがメモリ上に直接生成される(中間的にJavaソースは生成されない)  
+
*バイトコードがメモリ上に直接生成される(中間的に[[Java]]ソースは生成されない)  
 
*groovycでクラスファイルも作成可能
 
*groovycでクラスファイルも作成可能
  
32行目: 32行目:
 
*groovyコマンドで実行できる
 
*groovyコマンドで実行できる
 
====実行する====
 
====実行する====
  >groovy scriptname.groovy
+
  >groovy scriptname.groovy
 
====バインディング変数====
 
====バインディング変数====
 
*型もdefも使用しない
 
*型もdefも使用しない
39行目: 39行目:
 
*publicクラス定義を含むファイル名はクラスメイト一致する必要はない
 
*publicクラス定義を含むファイル名はクラスメイト一致する必要はない
 
*デフォルトでpublicアクセス
 
*デフォルトでpublicアクセス
*以下のようなクラスを定義したGroovyファイルは実行される
+
*以下のようなクラスを定義した[[Groovy]]ファイルは実行される
 
**mainメソッドを持つクラス
 
**mainメソッドを持つクラス
 
**JUnitなどのテストケース
 
**JUnitなどのテストケース
**Runnable実装クラス
+
**[[R]]unnable実装クラス
 
====メソッドとコンストラクタ====
 
====メソッドとコンストラクタ====
 
*Mapで引数と受け取ることで名前付き引数の利用が可能
 
*Mapで引数と受け取ることで名前付き引数の利用が可能
54行目: 54行目:
 
         "i am ${name}, ${age} years old."
 
         "i am ${name}, ${age} years old."
 
     }
 
     }
     def changeProfile(name='foo',age=1){
+
     def change[[Profile]](name='foo',age=1){
 
         this.name=name
 
         this.name=name
 
         this.age = age
 
         this.age = age
64行目: 64行目:
 
         def p = new Person(name:'yagi',age:45)
 
         def p = new Person(name:'yagi',age:45)
 
         println p.profile()
 
         println p.profile()
         p.changeProfile()
+
         p.change[[Profile]]()
 
         println p
 
         println p
 
     }
 
     }
 
  }
 
  }
  
  > groovy .\Person.groovy
+
  > groovy .\Person.groovy
 
  i am yagi, 45 years old.
 
  i am yagi, 45 years old.
 
  i am foo, 1 years old.
 
  i am foo, 1 years old.
===GroovyBeans===
+
===[[Groovy]]Beans===
 
====ゲッター、セッターの自動生成====
 
====ゲッター、セッターの自動生成====
 
*フィールドのアクセッサが自動生成される
 
*フィールドのアクセッサが自動生成される
92行目: 92行目:
 
  println "${bean.name},${bean.address},${bean.age},${bean.profAge}"
 
  println "${bean.name},${bean.address},${bean.age},${bean.profAge}"
  
  > groovy .\GroovyBeans.groovy
+
  > groovy .\[[Groovy]]Beans.groovy
 
  yagi,AICH,45,40
 
  yagi,AICH,45,40
 
===プロパティ、フィールド、メソッド参照===
 
===プロパティ、フィールド、メソッド参照===
110行目: 110行目:
 
  println '6.' + s.getProperty(propName)
 
  println '6.' + s.getProperty(propName)
  
  > groovy .\PropertyMethod.groovy
+
  > groovy .\PropertyMethod.groovy
 
  1.Sample
 
  1.Sample
 
  2.Sample
 
  2.Sample
129行目: 129行目:
 
  println '2.' + bean."${methodName}"()
 
  println '2.' + bean."${methodName}"()
  
  > groovy .\PropertyMethod.groovy
+
  > groovy .\PropertyMethod.groovy
 
  1.method
 
  1.method
 
  2.method
 
  2.method
137行目: 137行目:
 
*obj.metaClass.methods
 
*obj.metaClass.methods
  
  groovy:000> f = new File(/c:\work/)
+
  groovy:000> f = new File(/c:\work/)
  ===> c:\work
+
  ===> c:\work
  groovy:000> f.properties
+
  groovy:000> f.properties
  ===> [directory:true, canonicalFile:C:\work, file:false, freeSpace:80082784256, invalid:false, canonicalPath:C:\work, usableSpace
+
  ===> [directory:true, canonicalFile:C:\work, file:false, freeSpace:80082784256, invalid:false, canonicalPath:C:\work, usableSpace
 
  :80082784256, hidden:false, totalSpace:217750581248, path:c:\work, name:work, prefixLength:3, absolute:true, class:class java.io.
 
  :80082784256, hidden:false, totalSpace:217750581248, path:c:\work, name:work, prefixLength:3, absolute:true, class:class java.io.
 
  File, parentFile:c:\, absolutePath:c:\work, parent:c:\, absoluteFile:c:\work]
 
  File, parentFile:c:\, absolutePath:c:\work, parent:c:\, absoluteFile:c:\work]
  groovy:000> f.metaClass.methods
+
  groovy:000> f.metaClass.methods
  ===> [public boolean java.lang.Object.equals(java.lang.Object), public final native java.lang.Class java.lang.Object.getClass(),
+
  ===> [public boolean java.lang.Object.equals(java.lang.Object), public final native java.lang.Class java.lang.Object.getClass(),
 
  public native int java.lang.Object.hashCode(), public final native void java.lang.Object.notify(), public final native void java.
 
  public native int java.lang.Object.hashCode(), public final native void java.lang.Object.notify(), public final native void java.
 
  lang.Object.notifyAll(), public java.lang.String java.lang.Object.toString(), public final void java.lang.Object.wait() throws ja
 
  lang.Object.notifyAll(), public java.lang.String java.lang.Object.toString(), public final void java.lang.Object.wait() throws ja
151行目: 151行目:
 
     :
 
     :
 
*obj.metaClass.methods.name.sort().unique()
 
*obj.metaClass.methods.name.sort().unique()
  groovy:000> f.metaClass.methods.name.sort().unique()
+
  groovy:000> f.metaClass.methods.name.sort().unique()
  ===> [canExecute, canRead, canWrite, compareTo, createNewFile, createTempFile, delete, deleteOnExit, equals, exists, getAbsoluteF
+
  ===> [canExecute, canRead, canWrite, compareTo, createNewFile, createTempFile, delete, deleteOnExit, equals, exists, getAbsoluteF
 
  ile, getAbsolutePath, getCanonicalFile, getCanonicalPath, getClass, getFreeSpace, getName, getParent, getParentFile, getPath, get
 
  ile, getAbsolutePath, getCanonicalFile, getCanonicalPath, getClass, getFreeSpace, getName, getParent, getParentFile, getPath, get
  TotalSpace, getUsableSpace, hashCode, isAbsolute, isDirectory, isFile, isHidden, lastModified, length, list, listFiles, listRoots
+
  TotalSpace, getUsableSpace, hashCode, isAbsolute, isDirectory, isFile, isHidden, lastModified, length, list, listFiles, list[[R]]oots
  , mkdir, mkdirs, notify, notifyAll, renameTo, setExecutable, setLastModified, setReadOnly, setReadable, setWritable, toPath, toSt
+
  , mkdir, mkdirs, notify, notifyAll, renameTo, setExecutable, setLastModified, set[[R]]eadOnly, set[[R]]eadable, setWritable, toPath, toSt
  ring, toURI, toURL, wait]
+
  ring, toU[[R]]I, toU[[R]]L, wait]
 
===データ型===
 
===データ型===
 
====型指定を省略できる====
 
====型指定を省略できる====
168行目: 168行目:
 
  println i.class.name
 
  println i.class.name
  
  > groovy .\DataType.groovy
+
  > groovy .\DataType.groovy
 
  java.lang.Integer
 
  java.lang.Integer
 
====真偽値の扱い====
 
====真偽値の扱い====
187行目: 187行目:
 
|-
 
|-
 
|文字列
 
|文字列
|長さ>0
+
|長さ>0
 
|長さ0
 
|長さ0
 
|-
 
|-
210行目: 210行目:
 
  println map
 
  println map
  
  > groovy .\DataType.groovy
+
  > groovy .\DataType.groovy
 
  [1:one, 2:two]
 
  [1:one, 2:two]
 
====数値型の扱い====
 
====数値型の扱い====
242行目: 242行目:
 
  println c.class.name
 
  println c.class.name
  
  > groovy .\DataType.groovy
+
  > groovy .\DataType.groovy
 
  java.lang.Integer
 
  java.lang.Integer
 
  java.math.BigDecimal
 
  java.math.BigDecimal
249行目: 249行目:
 
*GString  
 
*GString  
 
**ダブルクオート、スラッシュで囲った定数中の「$変数名」[${式}」を実行時に展開する
 
**ダブルクオート、スラッシュで囲った定数中の「$変数名」[${式}」を実行時に展開する
*シングルクオートは、Javaの文字列と同義
+
*シングルクオートは、[[Java]]の文字列と同義
 
*/~/ \をエスケープ文字として扱わない、GStringを展開する
 
*/~/ \をエスケープ文字として扱わない、GStringを展開する
 
*ダブル、シングルクオートをそれぞれ3つで囲む、$/~/$と複数行
 
*ダブル、シングルクオートをそれぞれ3つで囲む、$/~/$と複数行
278行目: 278行目:
  
  
  > groovy .\Strings.groovy
+
  > groovy .\Strings.groovy
 
  1.123,246
 
  1.123,246
 
  2.$num,${num*2}
 
  2.$num,${num*2}
295行目: 295行目:
 
  6.c:\work
 
  6.c:\work
 
   c:\work\test
 
   c:\work\test
===クロージャ===
+
===[[クロージャ]]===
 
*生成時のコンテキストを含んだコードブロック
 
*生成時のコンテキストを含んだコードブロック
**クロージャが生成された場所で可視である変数を参照、変更可能
+
**[[クロージャ]]が生成された場所で可視である変数を参照、変更可能
 
*{~}で囲んだコードとして表記
 
*{~}で囲んだコードとして表記
 
   
 
   
307行目: 307行目:
 
  c();
 
  c();
  
  > groovy .\ClosureSample.groovy
+
  > groovy .\ClosureSample.groovy
 
  hello,Sat Mar 04 18:21:42 JST 2017
 
  hello,Sat Mar 04 18:21:42 JST 2017
  
====->を使って引数を与えることができる====
+
====->を使って引数を与えることができる====
*仮引数を指定しないと、引数を取らないクロージャとなる
+
*仮引数を指定しないと、引数を取らない[[クロージャ]]となる
 
   c = {
 
   c = {
       msg ->
+
       msg ->
 
       def d = new Date()
 
       def d = new Date()
 
       println "$msg,$d"
 
       println "$msg,$d"
328行目: 328行目:
 
   c('hello');  
 
   c('hello');  
  
  > groovy .\ClosureSample.groovy
+
  > groovy .\ClosureSample.groovy
 
  hello,Sat Mar 04 22:32:58 JST 2017
 
  hello,Sat Mar 04 22:32:58 JST 2017
 
====制御構造として利用====
 
====制御構造として利用====
335行目: 335行目:
 
  }
 
  }
  
  > groovy .\ClosureSample.groovy
+
  > groovy .\ClosureSample.groovy
 
  1,2,3,4,5,6,7,8,9,10,
 
  1,2,3,4,5,6,7,8,9,10,
 
====リソース開放やクローズ====
 
====リソース開放やクローズ====
 
*http://docs.groovy-lang.org/latest/html/documentation/working-with-io.html
 
*http://docs.groovy-lang.org/latest/html/documentation/working-with-io.html
  new File(/C:\Users\piroto\workspace\vscode\groovy_lesson\ClosureSample.groovy/).withReader {
+
  new File(/C:\Users\piroto\workspace\vscode\groovy_lesson\ClosureSample.groovy/).with[[R]]eader {
     reader ->
+
     reader ->
 
     reader.each{
 
     reader.each{
 
         println it
 
         println it
346行目: 346行目:
 
  }
 
  }
  
  > groovy .\ClosureSample.groovy
+
  > groovy .\ClosureSample.groovy
  new File(/C:\Users\piroto\workspace\vscode\groovy_lesson\ClosureSample.groovy/).withReader {
+
  new File(/C:\Users\piroto\workspace\vscode\groovy_lesson\ClosureSample.groovy/).with[[R]]eader {
     reader ->
+
     reader ->
 
     reader.each{
 
     reader.each{
 
         println it
 
         println it
358行目: 358行目:
 
  println even
 
  println even
  
  > groovy .\ClosureSample.groovy
+
  > groovy .\ClosureSample.groovy
 
  [2, 4, 6, 8, 10]
 
  [2, 4, 6, 8, 10]
 
=====collect=====
 
=====collect=====
364行目: 364行目:
 
  println square
 
  println square
  
  > groovy .\ClosureSample.groovy
+
  > groovy .\ClosureSample.groovy
 
  [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
 
  [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
 
===コレクション型===
 
===コレクション型===
370行目: 370行目:
 
====範囲====
 
====範囲====
 
  println (1..5)
 
  println (1..5)
  println (1 ..< 5)
+
  println (1 ..&lt; 5)
  
 > groovy .\CollectionSample.groovy
+
 &gt; groovy .\CollectionSample.groovy
 
  [1, 2, 3, 4, 5]
 
  [1, 2, 3, 4, 5]
 
  [1, 2, 3, 4]
 
  [1, 2, 3, 4]
385行目: 385行目:
 
  println list * 2
 
  println list * 2
 
  println list
 
  println list
  println list << [9,10]
+
  println list &lt;&lt; [9,10]
 
  println list
 
  println list
  
  > groovy .\CollectionSample.groovy
+
  &gt; groovy .\CollectionSample.groovy
 
  1
 
  1
 
  5
 
  5
411行目: 411行目:
 
  println map."$key"
 
  println map."$key"
  
  > groovy .\CollectionSample.groovy
+
  &gt; groovy .\CollectionSample.groovy
 
  [1:a, 2:b, 3:c]
 
  [1:a, 2:b, 3:c]
 
  a
 
  a
432行目: 432行目:
 
|-
 
|-
 
|.&
 
|.&
|メソッドをクロージャとして参照
+
|メソッドを[[クロージャ]]として参照
 
|-
 
|-
 
|.@
 
|.@
 
|フィールド/属性値を推定
 
|フィールド/属性値を推定
 
|-
 
|-
|<=>
+
|&lt;=&gt;
 
|大小比較
 
|大小比較
 
|-
 
|-
443行目: 443行目:
 
|範囲の生成(閉区間)
 
|範囲の生成(閉区間)
 
|-
 
|-
|..<
+
|..&lt;
 
|範囲の生成(半開区間)
 
|範囲の生成(半開区間)
 
|-
 
|-
462行目: 462行目:
 
|-
 
|-
 
|==~
 
|==~
|正規表現マッチ
+
|[[正規表現]]マッチ
 
|-
 
|-
 
|=~
 
|=~
512行目: 512行目:
 
  println cc.class.name
 
  println cc.class.name
  
  > groovy .\OperatorSample.groovy
+
  &gt; groovy .\OperatorSample.groovy
 
  === ?. ===
 
  === ?. ===
 
  null
 
  null
533行目: 533行目:
 
  java.lang.String
 
  java.lang.String
 
  java.lang.Character
 
  java.lang.Character
====その他の演算子====
+
====[[その他]]の演算子====
 
*== は、equals() 同じ意味
 
*== は、equals() 同じ意味
 
*javaでの==は、Object#is()を利用
 
*javaでの==は、Object#is()を利用
 
====マルチ代入====
 
====マルチ代入====
  groovy:000> l = [1,2,3]
+
  groovy:000&gt; l = [1,2,3]
  ===> [1, 2, 3]
+
  ===&gt; [1, 2, 3]
  groovy:000>
+
  groovy:000&gt;
  groovy:000> (a,b,c) = l
+
  groovy:000&gt; (a,b,c) = l
  ===> [1, 2, 3]
+
  ===&gt; [1, 2, 3]
  groovy:000> a
+
  groovy:000&gt; a
  ===> 1
+
  ===&gt; 1
  groovy:000> b
+
  groovy:000&gt; b
  ===> 2
+
  ===&gt; 2
  groovy:000> c
+
  groovy:000&gt; c
  ===> 3
+
  ===&gt; 3
 
===制御構造===
 
===制御構造===
 
====switch-case文====
 
====switch-case文====
554行目: 554行目:
 
====for文====
 
====for文====
 
*通常のforおよび拡張forが利用できる
 
*通常のforおよび拡張forが利用できる
  for (i=0; i<10; i++) {}
+
  for (i=0; i&lt;10; i++) {}
  for (int i: 0 ..<10) {}
+
  for (int i: 0 ..&lt;10) {}
 
* in の利用が可能
 
* in の利用が可能
 
  for (i in 0..10){}
 
  for (i in 0..10){}
 
====return文====
 
====return文====
*return 直後に関数やクロージャ末尾に到達することが確実である場合、省略可能
+
*return 直後に関数や[[クロージャ]]末尾に到達することが確実である場合、省略可能
 
===例外処理===
 
===例外処理===
 
*catchする例外の型を省略した場合、java.lang.Exception をcatchしているのと同じ
 
*catchする例外の型を省略した場合、java.lang.Exception をcatchしているのと同じ
 
*チェック例外を明示的に処理しなくともよい
 
*チェック例外を明示的に処理しなくともよい
===正規表現===
+
===[[正規表現]]===
 
*==~文字列全体にマッチするか
 
*==~文字列全体にマッチするか
 
*=~ パターンにマッチする部分が含まれるか(Matcherオブジェクトを生成)
 
*=~ パターンにマッチする部分が含まれるか(Matcherオブジェクトを生成)
573行目: 573行目:
 
  println (( 'pppiroto@gmail.com' =~ /[a-z]+/ )?"found":"not found")
 
  println (( 'pppiroto@gmail.com' =~ /[a-z]+/ )?"found":"not found")
  
  > groovy .\RegexSample.groovy
+
  &gt; groovy .\[[R]]egexSample.groovy
 
  true
 
  true
 
  false
 
  false
581行目: 581行目:
 
====後方参照、補足グループ====
 
====後方参照、補足グループ====
 
( 'pppiroto@gmail.com' =~ /([a-z])+@([a-z]+\.[a-z])+/ ).each{
 
( 'pppiroto@gmail.com' =~ /([a-z])+@([a-z]+\.[a-z])+/ ).each{
     g0, g1, g2 ->
+
     g0, g1, g2 -&gt;
 
     println "id=$g1,host=$g2,addr=$g0"
 
     println "id=$g1,host=$g2,addr=$g0"
 
  }
 
  }
589行目: 589行目:
 
  }
 
  }
  
  > groovy .\RegexSample.groovy
+
  &gt; groovy .\[[R]]egexSample.groovy
 
  id=o,host=gmail.c,addr=pppiroto@gmail.c
 
  id=o,host=gmail.c,addr=pppiroto@gmail.c
 
  pppiroto
 
  pppiroto
 
  gmail
 
  gmail
 
  com
 
  com
==Groovy API==
+
==[[Groovy]] API==
 
*http://docs.groovy-lang.org/latest/html/gapi/
 
*http://docs.groovy-lang.org/latest/html/gapi/
 
===ビルダー===
 
===ビルダー===
=====XML=====
+
=====[[XML]]=====
 
*http://www.ibm.com/developerworks/jp/java/library/j-pg05199/
 
*http://www.ibm.com/developerworks/jp/java/library/j-pg05199/
 
  import groovy.xml.MarkupBuilder
 
  import groovy.xml.MarkupBuilder
612行目: 612行目:
 
  println sw
 
  println sw
  
  > groovy .\XmlBuilderSample.groovy
+
  &gt; groovy .\XmlBuilderSample.groovy
  <Book>
+
  &lt;Book&gt;
   <Book type='book'>
+
   &lt;Book type='book'&gt;
     <Author>Hoge</Author>
+
     &lt;Author&gt;Hoge&lt;/Author&gt;
     <Price>1000</Price>
+
     &lt;Price&gt;1000&lt;/Price&gt;
   </Book>
+
   &lt;/Book&gt;
  </Book>
+
  &lt;/Book&gt;
==Groovy JDK (GDK)==
+
==[[Groovy]] JDK (GDK)==

2020年2月16日 (日) 04:26時点における最新版

Groovy

Gradle |

  • この本を参考にまとめる

概要

  • JVM上で動作する
  • Javaと直接的な連携が特徴
  • 動的言語であり直接スクリプトを実行できる
  • バイトコードがメモリ上に直接生成される(中間的にJavaソースは生成されない)
  • groovycでクラスファイルも作成可能

構成

import

デフォルトでインポート

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

別名

  • import as で別名を付けられる
import java.util.ArrayList as AL
def l = new AL()
l.add(1)
print l

スクリプト

  • 見た目上クラスに所属しないコード(コンパイルされると所属する)
  • groovyコマンドで実行できる

実行する

>groovy scriptname.groovy

バインディング変数

  • 型もdefも使用しない
  • 常にオブジェクト型

クラス定義

  • publicクラス定義を含むファイル名はクラスメイト一致する必要はない
  • デフォルトでpublicアクセス
  • 以下のようなクラスを定義したGroovyファイルは実行される
    • mainメソッドを持つクラス
    • JUnitなどのテストケース
    • Runnable実装クラス

メソッドとコンストラクタ

  • Mapで引数と受け取ることで名前付き引数の利用が可能
  • コンストラクタで名前付き引数を呼び出すとメンバを初期化(デフォルトコンストラクタ以外にコンストラクタを定義する場合は明示的に実装する)
  • 引数のデフォルト値
class Person {
    String name
    int age

    def profile(){
        "i am ${name}, ${age} years old."
    }
    def changeProfile(name='foo',age=1){
        this.name=name
        this.age = age
    }
    String toString(){
        profile()
    }
    static main(args) {
        def p = new Person(name:'yagi',age:45)
        println p.profile()
        p.changeProfile()
        println p
    }
}
> groovy .\Person.groovy
i am yagi, 45 years old.
i am foo, 1 years old.

GroovyBeans

ゲッター、セッターの自動生成

  • フィールドのアクセッサが自動生成される
  • アクセス修飾子を指定することで抑制できる
class SampleBean {
    def name
    def address
    private def age
    private def profAge;

    def getAddress(){
        address.toUpperCase();
    }
    def getProfAge(){
        age - 5;
    }
}
def bean = new SampleBean(name:'yagi',address:'aich',age:45)
println "${bean.name},${bean.address},${bean.age},${bean.profAge}"
> groovy .\GroovyBeans.groovy
yagi,AICH,45,40

プロパティ、フィールド、メソッド参照

フィールド、プロパティ参照方法

class Sample {
    def name = 'Sample'
}

def s = new Sample()

println '1.' + s.name
println '2.' + s.'name'
def propName = 'name'
println '3.' + s."${propName}"
println '4.' + s['name']
println '5.' + s[propName]
println '6.' + s.getProperty(propName)
> groovy .\PropertyMethod.groovy
1.Sample
2.Sample
3.Sample
4.Sample
5.Sample
6.Sample

メソッド参照

 class Sample {
    def method() {
        "method"
    }
}
def bean = new Sample()

println '1.' + bean.method()
def methodName = 'method'
println '2.' + bean."${methodName}"()
> groovy .\PropertyMethod.groovy
1.method
2.method

プロパティ、メソッドの一覧

  • obj.properties
  • obj.metaClass.methods
groovy:000> f = new File(/c:\work/)
===> c:\work
groovy:000> f.properties
===> [directory:true, canonicalFile:C:\work, file:false, freeSpace:80082784256, invalid:false, canonicalPath:C:\work, usableSpace
:80082784256, hidden:false, totalSpace:217750581248, path:c:\work, name:work, prefixLength:3, absolute:true, class:class java.io.
File, parentFile:c:\, absolutePath:c:\work, parent:c:\, absoluteFile:c:\work]
groovy:000> f.metaClass.methods
===> [public boolean java.lang.Object.equals(java.lang.Object), public final native java.lang.Class java.lang.Object.getClass(),
public native int java.lang.Object.hashCode(), public final native void java.lang.Object.notify(), public final native void java.
lang.Object.notifyAll(), public java.lang.String java.lang.Object.toString(), public final void java.lang.Object.wait() throws ja
va.lang.InterruptedException, public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException, public
final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException, public boolean java.io.File.canExecute(), publi
   :
  • obj.metaClass.methods.name.sort().unique()
groovy:000> f.metaClass.methods.name.sort().unique()
===> [canExecute, canRead, canWrite, compareTo, createNewFile, createTempFile, delete, deleteOnExit, equals, exists, getAbsoluteF
ile, getAbsolutePath, getCanonicalFile, getCanonicalPath, getClass, getFreeSpace, getName, getParent, getParentFile, getPath, get
TotalSpace, getUsableSpace, hashCode, isAbsolute, isDirectory, isFile, isHidden, lastModified, length, list, listFiles, listRoots
, mkdir, mkdirs, notify, notifyAll, renameTo, setExecutable, setLastModified, setReadOnly, setReadable, setWritable, toPath, toSt
ring, toURI, toURL, wait]

データ型

型指定を省略できる

  • 省略する場合、def を利用する
  • defを指定もしくは、defも省略した場合Object型を指定したのと同様
  • 型指定してもコンパイル時にチェックされるわけではない
  • 既存メソッドをオーバーライドする場合は、型指定省略不可

プリミティブ型の扱い

  • ほとんどの場合、ラッパー型に変換される
int i = 100
println i.class.name
> groovy .\DataType.groovy
java.lang.Integer

真偽値の扱い

  • ラッパー型として扱われる
整数 !0 0
浮動小数 !0.0 0.0
文字列 長さ>0 長さ0
リスト、マップ 空ではない
参照型 null以外 null
def map = [:]

if (!map) {
    map[1] = 'one'
}
if (map[1]) {
    map[2] = 'two'
}
println map
> groovy .\DataType.groovy
[1:one, 2:two]

数値型の扱い

  • 接尾語を指定しない浮動小数リテラルはBigDecimalとなる
接尾語
I/i Integer
L/l Long
F/f Float
D/d Double
G/g BigInteger/BigDecimal
def a = 1
def b = 1.0
def c = 1D

println a.class.name
println b.class.name
println c.class.name
> groovy .\DataType.groovy
java.lang.Integer
java.math.BigDecimal
java.lang.Double

文字列型

  • GString
    • ダブルクオート、スラッシュで囲った定数中の「$変数名」[${式}」を実行時に展開する
  • シングルクオートは、Javaの文字列と同義
  • /~/ \をエスケープ文字として扱わない、GStringを展開する
  • ダブル、シングルクオートをそれぞれ3つで囲む、$/~/$と複数行
def num = 123
println "1.$num,${num*2}"
println '2.$num,${num*2}'

println """
** 3. **
$num
********
"""
println 
** 4. **
$num
********


def s = /5.c:\work/
println s

def s2 = $/
6.c:\work
  c:\work\test
/$
println s2


> groovy .\Strings.groovy
1.123,246
2.$num,${num*2}

** 3. **
123
********


** 4. **
$num
********

5.c:\work

6.c:\work
  c:\work\test

クロージャ

  • 生成時のコンテキストを含んだコードブロック
    • クロージャが生成された場所で可視である変数を参照、変更可能
  • {~}で囲んだコードとして表記
def msg = 'hello'
c = {
    def d = new Date()
    println "$msg,$d"
}
c();
> groovy .\ClosureSample.groovy
hello,Sat Mar 04 18:21:42 JST 2017

->を使って引数を与えることができる

  • 仮引数を指定しないと、引数を取らないクロージャとなる
 c = {
     msg ->
     def d = new Date()
     println "$msg,$d"
 }
  c('hello'); 
groovy .\ClosureSample.groovy
hello,Sat Mar 04 22:30:42 JST 2017

引数リストを書かないと暗黙の引数itを一つとるとみなされる

 c = {
     def d = new Date()
     println "$it,$d"
 }
  c('hello'); 
> groovy .\ClosureSample.groovy
hello,Sat Mar 04 22:32:58 JST 2017

制御構造として利用

(1..10).each {
    print "$it,"
}
> groovy .\ClosureSample.groovy
1,2,3,4,5,6,7,8,9,10,

リソース開放やクローズ

new File(/C:\Users\piroto\workspace\vscode\groovy_lesson\ClosureSample.groovy/).withReader {
    reader -> 
    reader.each{
        println it
    }
}
> groovy .\ClosureSample.groovy
new File(/C:\Users\piroto\workspace\vscode\groovy_lesson\ClosureSample.groovy/).withReader {
    reader ->
    reader.each{
        println it
    }
}

コレクション処理

grep
even = (1..10).grep{it % 2 == 0}
println even
> groovy .\ClosureSample.groovy
[2, 4, 6, 8, 10]
collect
square = (1..10).collect{it ** 2}
println square
> groovy .\ClosureSample.groovy
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

コレクション型

範囲

println (1..5)
println (1 ..< 5)

 > groovy .\CollectionSample.groovy

[1, 2, 3, 4, 5]
[1, 2, 3, 4]

リスト

def list = [1,2,3,4,5]
println list[0]
println list[-1]
println list + [6,7,8]
println list
println list - [1,2]
println list
println list * 2
println list
println list << [9,10]
println list
> groovy .\CollectionSample.groovy
1
5
[1, 2, 3, 4, 5, 6, 7, 8]
[1, 2, 3, 4, 5]
[3, 4, 5]
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5, 1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5, [9, 10]]
[1, 2, 3, 4, 5, [9, 10]]

マップ

def map = [1:'a',2:'b',3:'c']
println map
println map[1]
map[1] = 'd'
println map
println (1 in map)
map = ['a':1,'b':2]
println map."a"
def key = 'b'
println map."$key"
> groovy .\CollectionSample.groovy
[1:a, 2:b, 3:c]
a
[1:d, 2:b, 3:c]
true
1
2

演算子

  • 演算子の多くは特定メソッド呼び出しのシンタックスシュガー
  • すべてではないが、オーバーロード可能
演算子 説明
?. nullセーフ
?: エルビス演算子
.& メソッドをクロージャとして参照
.@ フィールド/属性値を推定
<=> 大小比較
.. 範囲の生成(閉区間)
..< 範囲の生成(半開区間)
*. 展開ドット
* リスト展開
*: マップ展開
as 強制型変換
in 包含の判定
==~ 正規表現マッチ
=~ Matcherオブジェクト正史江
~ パターンオブジェクト生成
println "=== ?. ==="
def s = null
println s?.toUpperCase()

println "=== ?: ==="
def c = { it?:"empty"}
println c("value")
println c(null)

println "=== *. ==="
println  ( ['a','b','c'] *.toUpperCase() )

println "=== .& ==="
println Math.abs(-2.5)
def abs = Math.&abs
println abs(-2.5)

println "=== .@ ==="
class Test {
    def name = "field"
    def getName() {
        "method"
    }
}
def t = new Test()
println t.name
println t.@name

println "=== * ==="
println ([1,2,*[3,4]])

println "=== *: ==="
println ([1:'a',2:'b',*:[3:'c',4:'d']])

println "=== as ==="
def ss = "s"
println ss.class.name
def cc = ss as char
println cc.class.name
> groovy .\OperatorSample.groovy
=== ?. ===
null
=== ?: ===
value
empty
=== *. ===
[A, B, C]
=== .& ===
2.5
2.5
=== .@ ===
method
field
=== * ===
[1, 2, 3, 4]
=== *: ===
[1:a, 2:b, 3:c, 4:d]
=== as ===
java.lang.String
java.lang.Character

その他の演算子

  • == は、equals() 同じ意味
  • javaでの==は、Object#is()を利用

マルチ代入

groovy:000> l = [1,2,3]
===> [1, 2, 3]
groovy:000>
groovy:000> (a,b,c) = l
===> [1, 2, 3]
groovy:000> a
===> 1
groovy:000> b
===> 2
groovy:000> c
===> 3

制御構造

switch-case文

  • 機能的にif-elseと同等
  • isCase()を定義することでcase式で利用できるようになる

for文

  • 通常のforおよび拡張forが利用できる
for (i=0; i<10; i++) {}
for (int i: 0 ..<10) {}
  • in の利用が可能
for (i in 0..10){}

return文

  • return 直後に関数やクロージャ末尾に到達することが確実である場合、省略可能

例外処理

  • catchする例外の型を省略した場合、java.lang.Exception をcatchしているのと同じ
  • チェック例外を明示的に処理しなくともよい

正規表現

  • ==~文字列全体にマッチするか
  • =~ パターンにマッチする部分が含まれるか(Matcherオブジェクトを生成)
    • 真偽判定で利用される場合には、find()が暗黙で呼ばれる
println ( 'pppiroto@gmail.com' ==~ /[a-z]+@[a-z]+\.[a-z]+/ )
println ( 'pppiroto@gmail.com' ==~ /[a-z]+/ )
println ( 'pppiroto@gmail.com' =~ /[a-z]+/ )
println (( 'pppiroto@gmail.com' =~ /[a-z]+/ )?"found":"not found")
> groovy .\RegexSample.groovy
true
false
java.util.regex.Matcher[pattern=[a-z]+ region=0,18 lastmatch=]
found

後方参照、補足グループ

( 'pppiroto@gmail.com' =~ /([a-z])+@([a-z]+\.[a-z])+/ ).each{

    g0, g1, g2 ->
    println "id=$g1,host=$g2,addr=$g0"
}

('pppiroto@gmail.com' =~ /[(a-z)]+/ ).each{
    println it
}
>  groovy .\RegexSample.groovy
id=o,host=gmail.c,addr=pppiroto@gmail.c
pppiroto
gmail
com

Groovy API

ビルダー

XML
import groovy.xml.MarkupBuilder

def sw = new StringWriter()
def xml = new MarkupBuilder(sw)

xml.Book(null,{
    Book(type:'book',{
        Author('Hoge')
        Price(1000)
    })
})
println sw
> groovy .\XmlBuilderSample.groovy
<Book>
  <Book type='book'>
    <Author>Hoge</Author>
    <Price>1000</Price>
  </Book>
</Book>

Groovy JDK (GDK)