Java開発の強力な相棒として今すぐ使えるGroovy
-
Upload
yasuharu-nakano -
Category
Technology
-
view
5.181 -
download
2
Transcript of Java開発の強力な相棒として今すぐ使えるGroovy
![Page 1: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/1.jpg)
Yasuharu Nakano / @nobeans
Java開発の強力な相棒として今すぐ使える
2015-04-11 JJUG CCC 2015 Spring #ccc_g6
![Page 2: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/2.jpg)
中野 靖治@nobeans
所属:NTTソフトウェア株式会社 Grails推進室
職業:Grails Advocate
![Page 3: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/3.jpg)
概要
![Page 4: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/4.jpg)
Groovyとは
“Javaをもっとすごくしたもの” 「ポストJava」ではなく「Java強化外骨格」もしくは「Java拡張パック」のイメージ
Java VM上で動作する動的型付け言語 Rubyによく似た文法を持ち、生産性が高い Groovy界隈はRubyへのリスペクト成分が高め Grailsの旧名「Groovy on Rails」
2003年生まれ(平成生まれ)
![Page 5: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/5.jpg)
in Java
// HelloWorld.java public class HelloWorld { public static void main(String... args) { System.out.println("Hello, World!"); } }
//=> Hello, World!
![Page 6: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/6.jpg)
in Groovy
// HelloWorld.groovy public class HelloWorld { public static void main(String... args) { System.out.println("Hello, World!"); } }
//=> Hello, World!
Groovyとしてもvalidなコードなので拡張子を変えるだけでOK
![Page 7: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/7.jpg)
in Groovy
// HelloWorld.groovy public class HelloWorld { public static void main(String... args) { System.out.println("Hello, World!"); } }
//=> Hello, World!
セミコロンは省略可能
![Page 8: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/8.jpg)
in Groovy
// HelloWorld.groovy public class HelloWorld { public static void main(String... args) { System.out.println("Hello, World!") } }
//=> Hello, World!
Object#println()が使える(GDKのひとつ)
![Page 9: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/9.jpg)
in Groovy
// HelloWorld.groovy public class HelloWorld { public static void main(String... args) { println("Hello, World!") } }
//=> Hello, World!
スクリプト形式で実行可能(クラスが不要)
![Page 10: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/10.jpg)
in Groovy
// HelloWorld.groovy println("Hello, World!")
//=> Hello, World!
メソッド呼び出しの丸括弧は省略可能
![Page 11: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/11.jpg)
in Groovy
// HelloWorld.groovy println "Hello, World!"
//=> Hello, World!
![Page 12: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/12.jpg)
動的型付け言語
Groovyは基本的に動的型付け言語
![Page 13: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/13.jpg)
動的型付けの例
Integer num = "Hello"
//=> GroovyCastException: Cannot cast object 'Hello' with class 'java.lang.String' to class 'java.lang.Integer'
groovycでコンパイルには成功する
しかし、実行すると例外が発生する
![Page 14: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/14.jpg)
静的型付けサポート
Groovy 2.0から静的型付けのための機能が追加 @TypeChecked コンパイル時に静的に型チェックする ただし、実行時は動的型付けのまま
@CompileStatic 静的にコンパイルする 実行時に動的型付けによる機構は使われない Javaとほぼ同等レベルの性能に(理論上)
どちらもクラス単位、メソッド単位で指定できる ただし、明示的な型指定が省略できない 動的を前提とした一部の機能も使えなくなる
http://beta.mybetabook.com/showpage/508402720cf2ffb79bb046db
![Page 15: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/15.jpg)
Java言語との密な関係
Java(7以前)との文法の互換性が高い Java開発者なら非常にとっつきやすい ただし、Java 8のラムダ記法は未対応 代わりにクロージャを使う
すべてのJava APIがシームレスに呼び出せる 標準API、サードパーティのクラスもすべて普通に使える 更に「Groovy JDK(GDK)」と呼ばれる超便利メソッド群が標準クラスに追加されている!
コンパイルするとclassファイルになる 最低限、Java VMとgroovy-all.jarだけあれば実行できる
![Page 16: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/16.jpg)
Groovyの使いどころ
メインのプログラミング言語 Grails/Spring Boot/Vert.x/Android
設定ファイルの記述言語(as DSL) Gradle/Spring Boot/Spring Framework
システムのプラグイン機構/拡張ポイント Javaから外部のGroovyスクリプトを簡単に実行できる Jenkins
プロジェクトの開発支援スクリプト DBのセットアップ、Excel操作等
![Page 17: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/17.jpg)
Groovyの使いどころ
メインのプログラミング言語 Grails/Spring Boot/Vert.x/Android
設定ファイルの記述言語(as DSL) Gradle/Spring Boot/Spring Framework
システムのプラグイン機構/拡張ポイント Javaから外部のGroovyスクリプトを簡単に実行できる Jenkins
プロジェクトの開発支援スクリプト DBのセットアップ、Excel操作等
今日は後半でこの辺を中心に紹介します
![Page 18: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/18.jpg)
Groovy入門その前にまずは
![Page 19: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/19.jpg)
Javaとの文法の違い
![Page 20: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/20.jpg)
Javaとの文法の違い
セミコロンは省略可能 returnも省略可能 チェック例外のthrows宣言も省略可能 型宣言も省略可能 プリミティブ型はラッパー型 各種リテラル 数値/文字列/リスト/マップ
アクセス修飾子 メソッド呼び出し
![Page 21: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/21.jpg)
セミコロンは省略可能
// セミコロンは不要
int a = 1
// セミコロンはあってもOKだが、付けない方がお勧め
int b = 2;
![Page 22: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/22.jpg)
returnも省略可能
String hello() { // returnは省略できる
// Ruby等と同様に最後に評価された値が返る
"Hello" }
assert hello() == "Hello"
![Page 23: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/23.jpg)
チェック例外のthrows宣言も省略可能
String doWithoutThrows() { throw new Exception("チェック例外!")
}
try { doWithoutThrows() assert false } catch (Exception e) { assert e.getMessage() == "チェック例外!"
}
throwsがなくてもOK!
![Page 24: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/24.jpg)
型宣言も省略可能def キーワード Object型の別名として宣言時に使える
以下の場合、型宣言自体を省略可能(→Object型) メソッドや変数で、privateやstaticなどの修飾子が1つ以上ある場合 メソッドの仮引数
final helloPrefix = "Hello, "
public hello(name) { def message = helloPrefix + name return message }
省略はできるが、ドキュメンテーションとして考えると、公開APIのシグネチャでは型を明記する方が好ましい
def hoge = "ほげ"
![Page 25: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/25.jpg)
プリミティブ型で宣言しても実体はラッパー型 ただし、nullは代入不可能 また、最適化機構により、可能な場合において内部的にもプリミティブ型のまま扱われる場合もある
プリミティブ型はラッパー型
assert 1.getClass() == java.lang.Integer
double d = 1.0 assert d.getClass() == java.lang.Double
assert true.getClass() == java.lang.Boolean
// もちろんメソッドも呼べる
assert d.plus(2.5) == 3.5
// nullは代入不可能
d = null //=> GroovyCastException: Cannot cast object 'null' with class 'null' to class 'double'.
![Page 26: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/26.jpg)
リテラル:数値
Groovyの浮動小数リテラルはBigDecimal型 桁あふれや誤差を気にしないで演算できる プリミティブ型のように通常の中置演算子が使える
assert 5.3.getClass() == java.math.BigDecimal
// 普通に中置演算子も使える
assert (1.0 / 3) == 0.3333333333 assert (1.0 / 3).getClass() == java.math.BigDecimal
// Javaでは誤差が発生するが、GroovyはBigDecimalなので一致する
assert (1.0 -‐ (1.0 / 3.0)) == (2.0 / 3.0)
#ccc_cd3 でBigDecimal話がありましたね
![Page 27: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/27.jpg)
リテラル:文字列// 基本はJavaと同じくダブルクォーテーション
println "Hello, World!" //=> Hello, World!
// ${}によって変数を展開できる(紛らわしくなければ{}も省略できる)
String name = "World" assert "Hello, ${name}!" == "Hello, World!"
// 厳密にはGString型のリテラル
assert "Hello, ${name}!".getClass() == org.codehaus.groovy.runtime.GStringImpl
// 純粋にString型が必要な場合はシングルクォーテーションを使う
// Javaではchar型リテラルだったが、Groovyではchar型リテラルは無し
assert 'Hello, ${name}!' != "Hello, World!"
![Page 28: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/28.jpg)
リテラル:文字列
// トリプル「ダブルクォート」(ややこしい)
// 改行や単体のクォート文字列自体を含められる(GString型)
// トリプル「シングルクォート」にすると単なるString型になる(展開無し)
def s = "Third" println """First, "Second", ${s}. """
//=> // First, // "Second", // Third.
ヒアドキュメント風に使える
![Page 29: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/29.jpg)
リテラル:文字列
// 開始行の行末エスケープとString#stripMargin()を使うと、
// いい感じにインデントできて、読みやすい
def s = "Third" println """\ |First, |"Second", |${s}. |""".stripMargin()
//=> // First, // "Second", // Third.
GDKのString#stripMargin()と合わせて使うとインデントもいい感じにできる
![Page 30: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/30.jpg)
リテラル:文字列
// スラッシュクォート
// 単体バックスラッシュを特殊文字として扱わないため、エスケープが不要。
// 正規表現をシンプルに書ける
assert (/This is backslash '\n'/ == "This is backslash '\\n'") assert "Hello, World!".matches(/Hello,\s.*/)
// Pattern型ではなく、あくまでString型
assert (/Not Pattern, But String/.getClass() == String)
// 丸括弧で囲まないとコンパイルエラーになるケースがあるので注意
assert /Naked Slashed/ //=> "1 compilation error: unexpected token: /"
正規表現を書くときは断然コレ
![Page 31: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/31.jpg)
リテラル:リスト// 専用リテラルの導入により、シンプルにリストを記述できる
def l = [1, 2, 3, 4, 5]
assert l.size() == 5 assert l.getClass() == java.util.ArrayList
// 空リスト
assert [].size() == 0
// 要素へのアクセス
assert l[0] == 1 assert l[2..3] == [3, 4]
assert l.first() == 1 assert l.last() == 5
assert l.head() == 1 assert l.tail() == [2, 3, 4, 5]
![Page 32: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/32.jpg)
(参考)リテラル:セット
// セット専用のリテラルはないが、asによる型変換で表現できる
def s = [1, 2, 3, 4, 5] as Set
assert s.size() == 5 assert s.getClass() == java.util.LinkedHashSet
![Page 33: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/33.jpg)
リテラル:マップ
// 専用リテラルの導入により、シンプルにマップを記述できる def m = ['a': 1, 'b': 2, 'c': 3]
assert m.size() == 3 assert m.getClass() == java.util.LinkedHashMap
// 空マップ
assert [:].size() == 0
// キーに文字列を指定する場合はクォートを省略できる
assert m == [a: 1, b: 2, c: 3]
// 要素へのアクセス
assert m['a'] == 1 // 連想配列風
assert m.a == 1 // プロパティアクセス風
![Page 34: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/34.jpg)
アクセス修飾子
アクセス修飾子は基本的に飾りです privateメンバにもアクセスできる IDEなどで一応警告が出るぐらい
無印=public パッケージプライベートは存在しない 一応、アノテーションで強引に宣言できる
@PackageScope
基本は無印(public)でよい その他、ドキュメンテーション目的として... クラス内部だけで利用するものにprivateを付けたり 積極的に継承を想定しているものにprotectedを付けたり
![Page 35: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/35.jpg)
メソッド呼び出し
// 引数の丸括弧が省略できる
println("Hello") println "Hello"
// 引数がない場合は省略できない
println()
![Page 36: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/36.jpg)
メソッド呼び出し
def hello() { "Hello!" }
// Stringでメソッド名を指定できる
assert "hello"() == "Hello!"
// GStringを使ってもOK
def methodName = "hello" assert "$methodName"() == "Hello!"
![Page 37: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/37.jpg)
メソッド呼び出し
// 名前付き引数?
def hello(Map map) { "Hello, ${map.name}${map.period}" }
assert hello(period: "!", name: "World") == "Hello, World!"
// これの[]を省略できるイメージ
assert hello([period: "!", name: "World"]) == "Hello, World!"
![Page 38: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/38.jpg)
メソッド呼び出し
// 引数のデフォルト値
def bye(name = "World") { "Good-‐bye, ${name}." }
assert bye() == "Good-‐bye, World." assert bye("Yesterday") == "Good-‐bye, Yesterday."
![Page 39: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/39.jpg)
コンストラクタ呼び出し
class Sample { String a String b int c }
// 引数を受け取るコンストラクタを自前で書いていなければ、
// パラメータ付き引数を指定できる便利なコンストラクタが自動生成される
def sample = new Sample(a: "A", c: 3, b: "B")
println sample.dump() // デバッグ時に便利なGDK: Object#dump()
// => <Sample@3909c9e9 a=A b=B c=3>
![Page 40: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/40.jpg)
Groovyの各種機能
![Page 41: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/41.jpg)
クロージャ
他言語の第1級関数オブジェクトやクロージャと同等 JavaScript, Ruby, Perl, Lisp, ....
第一級オブジェクトとして、変数に代入したり引数に渡したりできる
高階関数
無名内部クラスやJava 8のラムダ記法よりも次の点で強力 クロージャを宣言した文法上のスコープ(レキシカルスコープ)にある変数(ローカル変数を含む)を参照・変更できる
![Page 42: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/42.jpg)
クロージャ:定義と実行
// クロージャを定義する
Closure c = { return "Hello, Closure!" }
// 実行する
assert c.call() == "Hello, Closure!"
// callを省略することもできる
assert c() == "Hello, Closure!"
![Page 43: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/43.jpg)
クロージャ:クロージャでの引数の受け取り// 引数なし
def c0 = {-‐> "Hello, Closure!" } assert c0.call() == "Hello, Closure!"
// 引数1つ
def c1 = { String name -‐> "Hello, ${name}!" } assert c1.call("Closure") == "Hello, Closure!"
// 引数2つ(片方を型省略してみる)
def c2 = { greeting, String name -‐> println "${greeting}, ${name}!" } assert c2.call("Hello", "Closure") == "Hello, Closure!"
// 引数宣言部「xx.. -‐>」を省略した場合、暗黙引数の「it」が使える
def c = { "Hello, ${it}!" } assert c.call("Closure") == "Hello, Closure!" assert c.call() == "Hello, null!" // 引数を省略時はnull
![Page 44: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/44.jpg)
クロージャ:クロージャを引数として渡す
// 渡されたクロージャを指定されたnameで実行するだけのメソッド
def justDoIt(String name, Closure closure) { closure.call(name) }
// 普通に丸括弧の中にクロージャを書いた場合
justDoIt("Taro", { name -‐> println "Hello, ${name}!" }) //=> Hello, Taro!
// 最後の引数がクロージャの場合はこのように丸括弧の外に出して書ける
justDoIt("Taro") { name -‐> println "Hello, ${name}!" } //=> Hello, Taro!
// このように、専用の文法があるかのように独自APIを定義できる
justDoIt("Taro") { name -‐> println "Hello, ${name}!" }
最後の引数がClosure型であるところがポイント
![Page 45: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/45.jpg)
(参考)クロージャ:高階関数とレキシカルスコープの例
def createIdGenerator(prefix) { // この実引数と
int counter = 1 // このローカル変数が(finalではない!)
Closure c = { "${prefix}-‐${counter++}" // クロージャごとに個別に保持される
} return c // クロージャを返す
}
def genA = createIdGenerator("A") assert genA() == "A-‐1" assert genA() == "A-‐2" assert genA() == "A-‐3"
def genB = createIdGenerator("B") assert genB() == "B-‐1" assert genB() == "B-‐2" assert genB() == "B-‐3"
assert genA() == "A-‐4"
元々createIdGeneraterメソッドのローカル変数であるcounter
が、クロージャごとに個別に管理されているのがわかる
![Page 46: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/46.jpg)
assertキーワード/Power Assert
Spockから正式採用したPower Assertが使える Spockの方が更に先に進んでいて若干高機能(適合率を表示するとか)
Assertion failed:
assert a.collect { it * 2 }.reverse() == [6, 4, 0] | | | | | [2, 4, 6] [6, 4, 2] false [1, 2, 3]
at ConsoleScript78.run(ConsoleScript78:2)
// わざと3つ目を間違えてみる
def a = [1, 2, 3] assert a.collect { it * 2 }.reverse() == [6, 4, 0]
![Page 47: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/47.jpg)
Groovy JDK/GDK
GroovyがJavaの標準APIに追加した便利なAPI群 Javaの不便な点をAPIレベルで改善できる
printlnもObjectに実装されたGDK APIのひとつ System.out.printlnに委譲しているだけ
後述するコレクションAPIもGDKとして実装されている
すべての品揃えは以下のAPIドキュメントを参照のこと http://docs.groovy-lang.org/docs/latest/html/groovy-jdk/
![Page 48: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/48.jpg)
GDKの例
// Groovy本家サイトのHTMLを表示する
println new URL("http://groovy-‐lang.org/").getText()
// ファイルの中身を表示する
println new File("/my/some.text/").getText()
![Page 49: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/49.jpg)
コレクション操作
各種の内部イテレーション記法が使える 外部イテレーション forやiteratorなどで外側から要素を回す
内部イテレーション 各要素に適用すべき処理をクロージャ/ラムダなどでコレクションに渡して、コレクション自体が内部でループする GroovyのコレクションAPIは、GDKとして提供されている Java 8のStream APIもこちら
![Page 50: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/50.jpg)
コレクション操作:リスト
List l = [1, 2, 3, 4, 5]
// 各要素に対してクロージャの処理を適用する
l.each { number -‐> print number } //=> 12345
// 各要素に対してクロージャの処理を適用した結果のリストを取得する
assert l.collect { it * 2 } == [2, 4, 6, 8, 10]
// 各要素に対してクロージャの処理を適用した結果が真の要素のみを残す
assert l.findAll { it % 2 == 0 } == [2, 4]
// 指定したセパレータで結合した文字列を返す
assert l.join(":") == "1:2:3:4:5"
// 合計値を算出する
assert l.sum() == 15
![Page 51: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/51.jpg)
コレクション操作:マップMap m = [a: 1, b: 2, c: 3]
// クロージャ引数を1つだけ宣言すると、Map.Entryが受け取れる
m.each { Map.Entry entry -‐> print entry.key + entry.value } //=> a1b2c3
// クロージャ引数を2つ宣言すると、それぞれキーと値が受け取れる
m.each { key, value -‐> print key + value } //=> a1b2c3
// 各要素に対してクロージャの処理を適用した結果のリストを取得する
assert m.collect { "${it.key}:${it.value}" } == ["a:1", "b:2", "c:3"]
// クロージャの返す値が最も大きい要素を取得する
assert m.max { it.value }.key == "c"
マップにも基本的に同じAPIが用意されている(コレクションの特性上、微妙に品揃えは違う)
![Page 52: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/52.jpg)
デフォルトimport済みパッケージ
高頻度で使うこれらのパッケージはデフォルトでimport済み java.lang.* java.io.* java.net.* java.util.* groovy.lang.* groovy.util.* java.math.BigDecimal java.math.BigInteger
(参考)別名をつけてimportすることもできるimport java.lang.NullPointerException as NPE
throw new NPE("aliased import sample")
![Page 53: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/53.jpg)
GroovyBeans
JavaBeansに対するGroovyの強化サポート プロパティに対するgetter/setterの自動生成
class Book { String title } def book = new Book(title: "プログラミングGROOVY")
// getterが自動生成されている
assert book.getTitle() == "プログラミングGROOVY"
// setterが自動生成されている
book.setTitle("JavaからGroovyへ")
assert book.getTitle() == "JavaからGroovyへ"
![Page 54: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/54.jpg)
GroovyBeansclass GroovyBeansSample { public String p = "PUBLIC" final String f = "FINAL" String g = "GetterImplemented" String getG() { "getGの戻り値: $g" }
}
def sample = new GroovyBeansSample()
// publicなどをアクセス修飾子を付けるとgetter/setterは自動生成されない
sample.getP() //=> groovy.lang.MissingMethodException sample.setP("x") //=> groovy.lang.MissingMethodException
// finalを付けるとsetterは自動生成されない
assert sample.getF() == "FINAL" sample.setF("x") //=> groovy.lang.MissingMethodException
// 自前で実装したアクセサメソッドは自動生成されない
assert sample.getG() == "getGの戻り値: GetterImplemented"
sample.setG("xxx") assert sample.getG() == "getGの戻り値: xxx"
常に無条件で自動生成するわけではない
![Page 55: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/55.jpg)
GroovyBeans
プロパティアクセスの簡略記法class Book { String title } def book = new Book(title: "プログラミングGROOVY")
// インスタンス変数への直接参照のようにみえるがgetterを経由している
assert book.title == "プログラミングGROOVY"
// インスタンス変数への直接代入のようにみえるがsetterを経由している
book.title = "JavaからGroovyへ"
assert book.title == "JavaからGroovyへ"
// getXxx()という名前の引数なしのメソッドであればプロパティ記法でアクセスできる
// つまり、GroovyBeansに限らず名前規約が一致していれば、この簡略記法は使える
assert book.class == book.getClass()
![Page 56: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/56.jpg)
Grape
Mavenリポジトリから直接Jarをダウンロードし、クラスパスに通してからスクリプトを実行できる ダウンロードしたファイルは $HOME/.groovy/grapes配下に格納される
@Grab('org.apache.commons:commons-‐lang3:3.2') import org.apache.commons.lang3.StringUtils
List l = [1, 2, 3, 4, 5]
assert StringUtils.join(l, ':') == "1:2:3:4:5"
// 本当はこの程度の処理であればGDKで十分
assert l.join(':') == "1:2:3:4:5"後半で示すサンプルはGrapeを使って即実行できるスクリプト形式にしている
![Page 57: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/57.jpg)
便利な演算子
等値演算子 == Javaではインスタンスの同一性のための使うが、Groovyではequals呼び出しになっている Stringの比較で普通に==が使える! インスタンス同一性のチェックにはObject#is()を使う
エルビス演算子 ?: A ?: B
三項演算子 A ? A : B の省略形
セーフナビゲーション演算子 ?. a?.b?.c()
nullではない場合のみ、右側の呼び出しを続行する
展開ドット演算子 *. [a:1, b:2, c:3]*.value == [1, 2, 3]
collect { it.value } の短縮形のイメージ
#ccc_cd1 で紹介されました!
#ccc_cd1 で紹介されました!
![Page 58: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/58.jpg)
レンジ(範囲)
範囲を表すコレクション groovy.lang.Range 始点と終点を指定してその間の要素をIterableに扱う
for (int i : 1..9) { // 閉区間(9を含む)
print i } //=> 123456789
for (int i : 1..<9) { // 半開区間(9を含まない)
print i } //=> 12345678
// Range#toList()でリストに変換できる
assert (1..5).toList() == [1, 2, 3, 4, 5]
![Page 59: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/59.jpg)
正規表現サポート
正規表現をサポートする演算子やリテラルがある
// 「==~」完全一致によるマッチング結果の真偽値を返す
assert "abc" ==~ /a.c/ assert ! ("abc" ==~ /bc/) // 部分一致ではない
// 実際は、Matcher#matches()の呼び出しになっている
assert "abc".matches(/a.c/) assert ! "abc".matches(/bc/)
// 「=~」部分一致によるマッチング結果のMatcherオブジェクトを返す
assert "abc" =~ /a.c/ assert "abc" =~ /bc/ // 部分一致OK
// 実は、演算自体の戻り値はMatcherオブジェクトになっている
// Matcherが真偽値判定されるタイミングで、
// Matcher#find()が裏で呼ばれてその結果が返っている
assert ("abc" =~ /a.c/).getClass() == java.util.regex.Matcher
![Page 60: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/60.jpg)
論理値/Groovy Truth
Groovyではboolean/Boolean以外の値についても、真偽判定できる
assert ! 0 // 整数: 0は偽
assert 1 // 整数: 0以外は真
assert ! [] // リスト: 空リストは偽
assert ["a"] // リスト: 空リスト以外は真
assert ! [:] // マップ: 空マップは偽
assert [key:'value'] // マップ: 空マップ以外は真
assert ! "" // 文字列: 空文字列は偽
assert "a" // 文字列: 空文字列以外は真
assert !("abcdefg" =~ /a.*X/) // 正規表現: マッチしないと偽
assert "abcdefg" =~ /cde/ // 正規表現: マッチすると真
assert ! null // nullは偽
assert new Object() // それ以外のオブジェクト: null以外は真
![Page 61: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/61.jpg)
演算子オーバーロード
GroovyではJavaと同等の各種演算子が使える 実は、それぞれの演算子は対応する特定のメソッド呼び出しに変換されている つまり、演算子オーバロードが可能 GDKでも多数活用されている 例えば、「+」→「plus()」、「-」→「minus()」、「<<」→「leftShift()」
演算子と対応するメソッドの一覧 http://groovy-lang.org/operators.html#Operator-Overloading
class MyObject { String name MyObject(name) { this.name = name } MyObject plus(MyObject o) { return new MyObject(name + ":" + o.name) } }
def obj1 = new MyObject("OBJECT_1") def obj2 = new MyObject("OBJECT_2")
def obj3 = obj1 + obj2 assert obj3.name == "OBJECT_1:OBJECT_2"
![Page 62: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/62.jpg)
AST変換
抽象構文木(Abstract Syntax Tree)レベルでのコード変換技術 コンパイルの過程で、アノテーションでマーキングした対象箇所に、任意のコードの追加・置換ができる Groovyシンタックスの意味自体を改変する「グローバルAST変換」技術もあるがあまり使われない
例 Grape(@Grab) ロギング(@Log, @Commons, @Log4j, @Slf4j) シングルトン(@Singleton) 不変オブジェクト(@Immutable) 自前クラスの基本要素(@ToString, @EqualsAndHashCode, @Canonical, @InheritConstructors)
![Page 63: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/63.jpg)
AST変換: @Grabと@Log
// Mavenセントラルリポジトリからダウンロード&クラスパスに指定
@Grab("log4j:log4j") import groovy.util.logging.Log4j
@Log4j class Sample { def doIt() { // ロガーとしてlog変数が使える
log.fatal "Hello" } }
new Sample().doIt() //=> FATAL -‐ Hello
![Page 64: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/64.jpg)
AST変換: @Singleton
@groovy.lang.Singleton class Sample { String value }
// インスタンス初期化機構とgetInstance()クラスメソッドが
// 追加されるので、シングルトンとしてすぐに使える
assert Sample.getInstance().value == null Sample.instance.value = "シングルトン"
assert Sample.instance.value == "シングルトン"
// もちろん同一インスタンス
assert sample.instance.is(Sample.instance)
![Page 65: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/65.jpg)
AST変換: @Immutable
@groovy.transform.Immutable class Sample { String value }
def sample = new Sample(value: "HOGE")
sample.value = "変更できない"
//=> groovy.lang.ReadOnlyPropertyException: // Cannot set readonly property: value for class: Sample
![Page 66: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/66.jpg)
AST変換: @ToString, @EqualsAndHashCode, @TupleConstructors
@groovy.transform.TupleConstructor @groovy.transform.ToString @groovy.transform.EqualsAndHashCode class Sample { String a String b int c }
// @TupleConstructorによって宣言したフィールドの順に引数を受け取るコンストラクタが生成される
def sample = new Sample("A", "B", 3)
// @ToStringによってそれっぽい文字列を構成するtoString()が生成される
println sample.toString() // => Sample(A, B, 3)
// @EqualsAndHashCodeによって、プロパティの値をベースにした等値判定をするequals()が生成される
assert sample == new Sample("A", "B", 3) assert sample != new Sample("A", "B", 123)
// もちろん、equals()の実装契約として必須であるhashCode()も合わせて実装されている
assert sample.hashCode() == new Sample("A", "B", 3).hashCode() assert sample.hashCode() != new Sample("A", "B", 123).hashCode()
// (参考) @Canonicalは、@ToStringと@EqualsAndHashCodeの組み合わせのエイリアス
![Page 67: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/67.jpg)
静的Groovy
@TypeChecked コンパイル時に静的型チェックする lintのようなもの 実行時はいつも通り動的に
@CompileStatic 指定した範囲を静的型付けとしてコンパイルする 実行時も静的に(性能的に有利) Groovyの動的な側面に依存した機能が使えない ダックタイピング、privateの呼び出し、など
性能的にカリカリにしたい箇所に、部分的に付けると良い
![Page 68: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/68.jpg)
静的Groovy: @TypeCheckedclass MyList { private List<String> list = [] def store(name) { list << name } }
def list = new MyList() list.store "A" list.store "B" list.store "C"
println list.dump() //=> <MyList@5c042a81 list=[A, B, C]>
StringインスタンスをObject型で受けとって、listに追加する
期待通り動く
![Page 69: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/69.jpg)
静的Groovy: @TypeCheckedclass MyList { private List<String> list = [] @groovy.transform.TypeChecked def store(name) { list << name } }
def list = new MyList() list.store "A" list.store "B" list.store "C"
println list.dump() //=> [Static type checking] -‐ Cannot call <T> java.util.List <String>#leftShift(T) with arguments [java.lang.Object] at line: 7, column: 9
コンパイル時にエラーが発生する
このメソッドを静的型チェックすると...
![Page 70: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/70.jpg)
静的Groovy: @TypeCheckedclass MyList { private List<String> list = [] @groovy.transform.TypeChecked def store(String name) { list << name } }
def list = new MyList() list.store "A" list.store "B" list.store "C"
println list.dump() //=> <MyList@5c042a81 list=[A, B, C]>
String型を明示すると...
また動くようになった!
![Page 71: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/71.jpg)
静的Groovy: 非@CompileStaticlong fib(long n) { if (n < 2) return 1 return fib(n -‐ 2) + fib(n -‐ 1) }
def start = System.currentTimeMillis()
def num = 40 def ans = fib(num) println "fib($num) = ${ans}"
println "Total: ${System.currentTimeMillis() -‐ start} msec"
//=> fib(40) = 165580141 // Total: 1575 msec
![Page 72: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/72.jpg)
静的Groovy: @CompileStaticimport groovy.transform.CompileStatic
@CompileStatic long fib(long n) { if (n < 2) return 1 return fib(n -‐ 2) + fib(n -‐ 1) }
def start = System.currentTimeMillis()
def num = 40 def ans = fib(num) println "fib($num) = ${ans}"
println "Total: ${System.currentTimeMillis() -‐ start} msec"
//=> fib(40) = 165580141 // Total: 569 msec 約3倍!<1575 msec
![Page 73: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/73.jpg)
(参考)AST変換: @Memoizedimport groovy.transform.Memoized
@Memoized long fib(long n) { if (n < 2) return 1 return fib(n -‐ 2) + fib(n -‐ 1) }
def start = System.currentTimeMillis()
def num = 40 def ans = fib(num) println "fib($num) = ${ans}"
println "Total: ${System.currentTimeMillis() -‐ start} msec"
//=> fib(40) = 165580141 // Total: 4 msec !!!!!!?????? <569 msec <1575 msec
参照透過な関数の場合、メモ化(引数と結果の組み合わせをキャッシュ)の効果が強力に活
用できる場合がある
![Page 74: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/74.jpg)
Groovy コードの実行
![Page 75: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/75.jpg)
実行可能なコード形式
![Page 76: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/76.jpg)
実行可能なコード形式
Groovyプログラムとして実行可能なのは... mainメソッド持つクラス(Javaと同等) Groovyスクリプト JUnitのテストケース Runnableの実装クラス
![Page 77: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/77.jpg)
mainメソッド持つクラス
// in HelloMain.groovy
class HelloMain { static void main(String... args) { println "Hello, Main!" } }
//=> Hello, Main!
![Page 78: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/78.jpg)
Groovyスクリプト
// in hello.groovy
println "Hello, Script!"
//=> Hello, Script!
クラスの外側のルートレベルで直接コードが書かれている=Groovyスクリプト
ちなみに、コンパイルされると、Scriptクラスのインスタンスになる
public class hello extends groovy.lang.Script { public static transient boolean __$stMC; public hello(); public hello(groovy.lang.Binding); public static void main(java.lang.String...); public java.lang.Object run(); protected groovy.lang.MetaClass $getStaticMetaClass(); }
![Page 79: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/79.jpg)
JUnitのテストケース
// in HelloTest.groovy
import junit.framework.TestCase
class HelloTest extends TestCase { void testHello() { println "Hello, JUnit!" } }
//=> .Hello, JUnit! // // Time: 0.047 // // OK (1 test) //
GroovyがJUnitを同梱しているので別途JARを用意する必要はない
![Page 80: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/80.jpg)
Runnableの実装クラス
// in HelloRunnable.groovy
class HelloRunnable implements Runnable { void run() { println "Hello, Runnable!" } }
//=> Hello, Runnable!
![Page 81: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/81.jpg)
実行可能なコード形式
Groovyプログラムとして実行可能なのは... mainメソッド持つクラス(Javaと同等) Groovyスクリプト JUnitのテストケース Runnableの実装クラス
今回のケースではとりあえず、これで十分
![Page 82: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/82.jpg)
実行方法
![Page 83: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/83.jpg)
各種実行方法
groovy java -jar groovy-all.jar
groovyc + java groovyConsole groovysh GroovyServ スクリプト起動の高速化
Groovy Web Console https://groovyconsole.appspot.com/
![Page 84: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/84.jpg)
各種実行方法
groovy java -jar groovy-all.jar
groovyc + java groovyConsole groovysh GroovyServ スクリプト起動の高速化
Groovy Web Console https://groovyconsole.appspot.com/
だいたいこの辺を使っておけばOK
![Page 85: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/85.jpg)
groovyコマンド
![Page 86: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/86.jpg)
java -jar groovy-all.jar == groovyコマンド
All-In-OneのJARファイルさえあれば、groovyコマンドがなくても実行できる!
![Page 87: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/87.jpg)
groovyc + java
滅多に使わない
![Page 88: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/88.jpg)
groovyConsole
編集して、Ctrl+Rで実行できる
実行結果を表示Ctrl+Wでクリア
引数なしでもOK
![Page 89: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/89.jpg)
groovysh
限定的ながらもTabでコード補完ができる
![Page 91: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/91.jpg)
Groovy web console
クリックで実行
https://groovyconsole.appspot.com/
インストール不要で手軽に試せる
![Page 92: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/92.jpg)
ユースケース
![Page 93: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/93.jpg)
(再掲)Groovyの使いどころ
メインのプログラミング言語 Grails/Spring Boot/Vert.x/Android
設定ファイルの記述言語(as DSL) Gradle/Spring Boot/Spring Framework
システムのプラグイン機構/拡張ポイント Javaから外部のGroovyスクリプトを簡単に実行できる Jenkins
プロジェクトの開発支援スクリプト DBのセットアップ、Excel操作等
![Page 94: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/94.jpg)
開発支援ツールとしての活用
Groovyは、たとえ対象システムの開発言語として採用しない場合でも、Javaによる開発を支援するツールとして非常に有用
なるほどね
![Page 95: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/95.jpg)
Java APIのお試し
![Page 96: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/96.jpg)
例えば
標準APIを試す ○○の場合はどういう動作をするんだったっけ? 正規表現はこれで良いのかな?
初めて使うサードパーティ製のライブラリを試す
![Page 97: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/97.jpg)
お試し環境
groovyConsole上で試す シンプルなエディタで試行錯誤できる Grapeを使ってサードパーティライブラリも試せる わかりやすくてお手軽
groovyshで試す JavaとGroovyの標準APIであれば、Tabによるコード補完が効く点でちょっと便利
エディタ+groovy (or GroovyServ) エディタの機能ですぐに実行できる環境をつくると便利 (例)vim + quickrun.vim + GroovyServ http://nobeans.hatenablog.com/entry/20111024/1319435155
ちなみに、この資料のサンプルコードはほとんどgroovyConsoleで書きました
![Page 98: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/98.jpg)
groovyConsoleの例
![Page 99: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/99.jpg)
XMLのパース
![Page 100: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/100.jpg)
例えば
設定ファイル内容の一覧を出力する JUnitのテストレポートをパースして自動的に進捗報告資料に追加する Rest APIの結果をチェックする
![Page 101: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/101.jpg)
XmlParser/XmlSlurper
Groovy標準APIのXmlParserが便利 兄弟分として XmlSlurper(~すらーぱー)がある XmlParser:DOM的(インメモリ、変更可能) XmlSlurper:SAX的(ストリーム処理、参照専用)
細かい点で差異はあるものの、シンプルな参照に限定したAPIの使い勝手はほぼ同じ メモリ展開が難しい巨大なファイルを対象とするのでなければ、XmlParserを選択しておけばOK
![Page 102: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/102.jpg)
XMLParserで属性やテキストを参照する例def inputXml = """ <root> <items> <item id="1" name="あいうえお">OK</item>
<item id="2" name="かきくけこ">NG</item>
<item id="3" name="さしすせそ">OK</item>
</items> </root> """ def root = new XmlParser().parseText(inputXml) // <root>に対応するgroovy.util.Nodeオブジェクト
// すべてのitem要素をフォーマットして出力する
root.items.item.each { Node item -‐> println "${item.@id}: ${item.@name} => ${item.text()}" } //=> 1: あいうえお => OK
// 2: かきくけこ => NG
// 3: さしすせそ => OK
// OKのitem要素のみをフォーマットして出力する
root.items.item.findAll { it.text() == "OK" }.each { println "${it.@id}: ${it.@name} => ${it.text()}" } //=> 1: あいうえお => OK
// 3: さしすせそ => OK
この時点でXMLはパースされて、Nodeツリーがメモリ上に展開済み
GPathという記法でNodeのコレクションを特定
属性値は「@+属性名」、子要素のテキストは「text()」で参照
each, findAllなどのコレクション操作がそのまま適用できる
![Page 103: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/103.jpg)
HTML/XMLの出力
![Page 104: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/104.jpg)
例えば
自動的に収集した情報を元にHTMLレポートを出力する システムにインポートするXMLファイルを生成する
![Page 105: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/105.jpg)
MarkupBuilder
Groovy標準APIのMarkupBuilderが便利 タグでマークアップされたテキストを生成する 波括弧のブロックで階層構造を表現できる if文やループ制御構文が使える
![Page 106: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/106.jpg)
マップの情報を元にHTMLを出力する例def generateHtml = { data, writer -‐> def reportTitle = '試験実施日時報告'
def formatCount = { now, latest -‐> def diffCount = now -‐ latest return "${now} (${diffCount > 0 ? "+" : ""}${diffCount})" } new groovy.xml.MarkupBuilder(writer).html { head { title reportTitle } body(style: "background: #afa") { h1 reportTitle h2 '試験件数等'
ul { li "試験項目数: ${formatCount(data.tests, data.latest.tests)}"
li "終了件数: ${formatCount(data.done, data.latest.done)}"
li "バグ件数: ${formatCount(data.issues, data.latest.issues)}"
} h2 '備考'
if (data.remarks) { ul { data.remarks.each { li(it) } } } } } }
def data = [ tests: 1230, done: 350, issues: 123, latest: [tests: 1235, done: 320, issues: 93], remarks: ["進捗は特に問題なし", "インフルエンザが流行中なので不安"]
] new File("/tmp/daily-‐test-‐report.html").withWriter { writer -‐> generateHtml(data, writer) }
![Page 107: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/107.jpg)
マップの情報を元にHTMLを出力する例 //... new groovy.xml.MarkupBuilder(writer).html { head { title reportTitle } body(style: "background: #afa") { h1 reportTitle h2 '試験件数等'
ul { li "試験項目数: ${formatCount(data.tests, data.latest.tests)}"
li "終了件数: ${formatCount(data.done, data.latest.done)}"
li "バグ件数: ${formatCount(data.issues, data.latest.issues)}"
} h2 '備考'
if (data.remarks) { ul { data.remarks.each { li(it) } } } } } //...
![Page 108: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/108.jpg)
MarkupBuilderについてもう少し補足def builder = new groovy.xml.MarkupBuilder()
def existMethod(a) { "EXIST_METHOD: ${a}" }
// 最初の呼び出しで使った名前がルート要素のタグ名になる
builder.aaa { // 存在しないメソッド名で呼び出すと要素宣言と見なされる。引数は子要素になる。
bbb "BBB" // 引数をマップで指定すると属性値になる
ccc(c1: "C1", c2: "C2")
// 引数としてクロージャを渡すとネストになる
ddd { xxx "XXX" }
// 制御構文がそのまま使える
if (false) { // ここが実行されなければ出力されない
ignoredThis "IGNORED" } // 存在するメソッドであれば単にそのメソッドが呼ばれるだけで要素は生成されない
// 存在しないメソッドを実行しようとすることが、要素生成のトリガとなる
existMethod "ただのメソッド呼び出し"
}
<aaa> <bbb>BBB</bbb> <ccc c1='C1' c2='C2' /> <ddd> <xxx>XXX</xxx> </ddd> </aaa>
このように、Groovyの「*Builder」は存在しないメソッド呼び出し(methodMissing)をトリガにして構造をビルドしていくクラスになっている
![Page 109: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/109.jpg)
HTMLスクレイピング
![Page 110: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/110.jpg)
例えば
定期レポートのための情報を収集する 開発中のWebアプリのテストの一環として、ある画面のHTMLを取得して、内容をチェックする
![Page 111: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/111.jpg)
HTMLスクレイピング
URL#getText() HTMLテキストを取得すればいい場合は一番簡単
XmlParser/XmlSlurper 整形式であるXHMLの場合は単品でOK 非整形式のHTMLの場合はNekoHTMLを併用すればOK http://nekohtml.sourceforge.net/
jsoup jQuery風のセレクタAPIが使える http://jsoup.org/
![Page 112: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/112.jpg)
HTMLスクレイピング: URL#getText()String html = new URL("http://groovy-‐lang.org/").text
// 1行ずつチェックしてURLをパースする
def urls = html // 1行ずつのリストにする
.readLines() // 行中にURLパターンがあったらそれを返す(なければnull)
.collect { line -‐> if (line =~ $/.*(https?://[a-‐zA-‐Z0-‐9%?._]+).*/$) { return java.util.regex.Matcher.lastMatcher.group(1) } } // nullを除外する
.findAll { it != null } // 重複したURLを除去する
.unique()
// ソートして表示する
urls.sort().each { println it }
![Page 113: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/113.jpg)
HTMLスクレイピング: XmlParser + NekoHTML@Grab('net.sourceforge.nekohtml:nekohtml:1.9.21') import org.cyberneko.html.parsers.SAXParser import groovy.util.Node
def parser = new XmlParser(new SAXParser())
Node html = parser.parse("http://groovy-‐lang.org/")
// 1行ずつチェックしてURLをパースする
def urls = html // html配下のすべての子要素のaタグのhref属性値を集める
.'**'.A.@href // http(s)のものだけ抽出する
.findAll { it ==~ /https?:.*/ } // 重複したURLを除去する
.unique()
// ソートして表示する
urls.sort().each { println it }
![Page 114: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/114.jpg)
HTMLスクレイピング: jsoup@Grab('org.jsoup:jsoup:1.8.1') import org.jsoup.Jsoup import org.jsoup.nodes.Document
Document doc = Jsoup.connect("http://groovy-‐lang.org/").get()
def urls = doc // すべてのaタグのhref属性を集める
.select('a')*.attr("href") // http(s)のものだけ抽出する
.findAll { it ==~ /https?:.*/ } // 重複したURLを除去する
.unique()
// ソートして表示する
urls.sort().each { println it }
![Page 115: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/115.jpg)
Groovy SQLによる RDBMS操作
![Page 116: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/116.jpg)
例えば
テスト用ダミーデータをDBに大量投入する 定期レポートのための情報を収集する 保守のためデータベースの内容を定期的に監視する あるシステムから別のシステムにデータを移行する
![Page 117: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/117.jpg)
Groovy SQL
Groovy標準APIのGroovy SQLが便利 クエリ発行と結果のResultSetからの値の取り出しなどが簡単に実行できる DataSetを使うと、コレクション操作のようにレコードの追加やイテレーションが実行できる
![Page 118: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/118.jpg)
Groovy SQLでH2を操作する@Grab('com.h2database:h2') @GrabConfig(systemClassLoader=true) // JDBCはシステムクラスローダから探されるので必要
import groovy.sql.Sql
// 別途DataSourceやConnectionを用意するなら、Sqlのコンストラクタに渡せばOK
def db = Sql.newInstance("jdbc:h2:mem:sample", "org.h2.Driver")
// Sql#execute()でDDLを実行する
db.execute """ create table person ( name varchar(255), age int ) """
// Sql#executeUpdate()使うと、変更した行数が返る
insertSql = "insert into person (name, age) values (?, ?)" assert db.executeUpdate(insertSql, ['Mike', 13]) == 1 assert db.executeUpdate(insertSql, ['Junko', 14]) == 1
// Sql#eachRow()は1行ごとに処理する(リソース低負荷)
db.eachRow('select * from person') { row -‐> println row.name } //=> Mike // Junko
// Sql#rows()は結果をすべてメモリ上に取得する(リソース高負荷)
println db.rows('select * from person').collect { it.name } //=> [Mike, Junko]
![Page 119: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/119.jpg)
DataSetを使う例@Grab('com.h2database:h2') @GrabConfig(systemClassLoader=true) // JDBCはシステムクラスローダから探されるので必要
import groovy.sql.Sql
// 別途DataSourceやConnectionを用意するなら、Sqlのコンストラクタに渡せばOK
def db = Sql.newInstance("jdbc:h2:mem:sample", "org.h2.Driver")
// Sql#execute()でDDLを実行する
db.execute(""" create table person ( name varchar(255), age int ) """)
// DataSetを使うとコレクションオブジェクト風にレコード操作ができる
import groovy.sql.DataSet
DataSet people = db.dataSet('person') people.add(name: 'Mike', age:13) people.add(name: 'Junko', age: 14) people.add(name: 'Ken', age: 23)
people.each { println "${it.name} (${it.age})" } //=> Mike (13) // Junko (14) // Ken (23)
![Page 120: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/120.jpg)
GExcelAPIによる Excel操作
![Page 121: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/121.jpg)
例えば
ダミーデータの定義表として読み込む Excelデータから特定セルの値を読み込んで集計する コード生成の入力データとして
![Page 122: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/122.jpg)
GExcelAPI
https://github.com/nobeans/gexcelapi Apache POIのGroovy風ラッパーライブラリ
POIを直接使った場合、セルを特定するインデックス指定がとても分かりづらい
GExcelAPIを使うと、Excelのセルラベルである「A1」でアクセスできる!
![Page 123: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/123.jpg)
GExcelAPI@GrabResolver(name="bintray", root="http://dl.bintray.com/nobeans/maven") @Grab("org.jggug.kobo:gexcelapi:0.4") import org.jggug.kobo.gexcelapi.GExcel
def book = GExcel.open("/tmp/sample.xlsx") def sheet = book[0] // 1シート目
// Excel風なDSLでセルの値を取得する
println sheet.A1.value //=> A1の値
println sheet.B2.value //=> B2の値
println sheet.C3.value //=> 303.0 println sheet.D4.dateCellValue.format("yyyy-‐MM-‐dd") //=> 2015-‐02-‐29
// 指定した矩形内でイテレーション
sheet.A1_D4.each { row -‐> println row } //=> [[A1の値, B1の値, 301.0, 42041.0],
// [A2の値, B2の値, 302.0, 42042.0],
// [A3の値, B3の値, 303.0, 42043.0],
// [A4の値, B4の値, 304.0, 42044.0]]
日付型のセルはプログラマが日付であることを意識して取得しなければならない
![Page 124: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/124.jpg)
テンプレートエンジン
![Page 125: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/125.jpg)
例えば
定型レポートをテンプレートから生成する 何らかの定義情報を元に、ソースコードを生成する
![Page 126: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/126.jpg)
テンプレートエンジン?
複数行文字列リテラル+ String#stripMargin() SimpleTemplateEngine
![Page 127: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/127.jpg)
複数行文字列リテラル+stripMargin()
String applyTemplate(name, title) { return """\ |こんにちは、${name}さん
| |本日は、${title}をご案内させていただきます。
|... |""".stripMargin() }
println applyTemplate("日本 太郎", "プログラミングGROOVY")
//=> こんにちは、日本 太郎さん
// // 本日は、プログラミングGROOVYをご案内させていただきます。
// ...
先頭行のエスケープ付き改行とstripMarginを使うことで、
インデントを自然な形に揃えられる
![Page 128: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/128.jpg)
SimpleTemplateEngine
import groovy.text.SimpleTemplateEngine
String applyTemplate(name, title) { String templateText = '''\ |こんにちは、${name}さん
| |本日は、<%= title %>をご案内させていただきます。
|... |'''.stripMargin() def template = new SimpleTemplateEngine().createTemplate(templateText)
def binding = [name: name, title: title] return template.make(binding)
}
println applyTemplate("日本 太郎", "プログラミングGROOVY")
//=> こんにちは、日本 太郎さん
// // 本日は、プログラミングGROOVYをご案内させていただきます。
// ...
JSP形式の変数展開もできる
テンプレート文字列を外部ファイルから読み込むようにすると良い(例)new File("template.tpl").text
#ccc_g4 でGradleからの利用例が紹介されたらしい?
![Page 129: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/129.jpg)
(再掲)Groovyの使いどころ
メインのプログラミング言語 Grails/Spring Boot/Vert.x/Android
設定ファイルの記述言語(as DSL) Gradle/Spring Boot/Spring Framework
システムのプラグイン機構/拡張ポイント Javaから外部のGroovyスクリプトを簡単に実行できる Jenkins
プロジェクトの開発支援スクリプト DBのセットアップ、Excel操作等
万が一時間があれば紹介したい
![Page 130: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/130.jpg)
Javaから Groovyを使う
![Page 131: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/131.jpg)
例えば
システムにプラグイン機構を追加する 頻繁に変更されるビジネスロジック部分をGroovyスクリプトとして外だしする アプリの一部だけでも良いからGroovyで書きたい
![Page 132: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/132.jpg)
JavaからGroovyを使う
Groovyで実装したクラスをJavaから利用する コンパイルしたクラスを同梱する Groovyのコンパイルには、groovycコマンドやGradleを使う クラスパスにgroovy-all.jarが含まれてさえいれば、普通に使える
Groovyソースコードから動的にクラスをロードする groovy-all.jarはもちろん必要
GroovyスクリプトをJavaから動的に実行する(CGI風) GroovyShell ちょっとスクリプトを実行するぐらいの用途ならば手軽で便利
GroovyScriptEngine 対象ディレクトリを事前指定するため、複数のGroovyスクリプトを取り扱うようなプラグイン機構などに向いている
![Page 133: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/133.jpg)
コンパイルしたクラスを同梱する
コンパイルしたGroovyのクラスがクラスパスに通っていれば、普通に使える
![Page 134: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/134.jpg)
Groovyソースコードから動的にクラスをロードする
GroovyClassLoaderを使うと、Groovyソースコードから実行時に動的にクラスロードできる
![Page 135: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/135.jpg)
GroovyスクリプトをJavaから実行する: GroovyShell
Bindingというマップ的なオブジェクトを利用して、スクリプト上で利用可能な暗黙変数を渡すことができる
![Page 136: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/136.jpg)
GroovyスクリプトをJavaから実行する: GroovyScriptEngine
スクリプトのルートディレクトリをあらかじめ指定しておく
![Page 137: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/137.jpg)
まとめ
![Page 138: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/138.jpg)
Groovyの使いどころ
メインのプログラミング言語 Grails/Spring Boot/Vert.x/Android
設定ファイルの記述言語(as DSL) Gradle/Spring Boot/Spring Framework
システムのプラグイン機構/拡張ポイント Javaから外部のGroovyスクリプトを簡単に実行できる Jenkins
プロジェクトの開発支援スクリプト DBのセットアップ、Excel操作等
![Page 139: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/139.jpg)
というわけで、まずはこの辺から始めてみませんか?
メインのプログラミング言語 Grails/Spring Boot/Vert.x/Android
設定ファイルの記述言語(as DSL) Gradle/Spring Boot/Spring Framework
システムのプラグイン機構/拡張ポイント Javaから外部のGroovyスクリプトを簡単に実行できる Jenkins
プロジェクトの開発支援スクリプト DBのセットアップ、Excel操作等
これもおすすめ
![Page 140: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/140.jpg)
参考情報
![Page 141: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/141.jpg)
プログラミングGroovy
Java技術者を対象に、Groovyの基本から応用までを丁寧に説明しています 対象のGroovyバージョンが1.8とだいぶ古いのですが、記載されている内容はほとんど陳腐化してないので、今でもお勧めの一冊
http://gihyo.jp/book/2011/978-4-7741-4727-7
![Page 142: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/142.jpg)
Gradle徹底入門
2014/11発売 世界に現存するGradle本の中でここまで突っ込んで説明したものはほぼないレベル 分厚いですが、その分情報がたっぷりです (私もレビュアで参加)
http://www.shoeisha.co.jp/book/detail/9784798136431
![Page 143: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/143.jpg)
その他、参考URL
サンプルコード https://github.com/nobeans/jjug-ccc-2015-spring-groovy
Groovy Home http://groovy-lang.org/
Groovy JDK http://docs.groovy-lang.org/docs/latest/html/groovy-jdk/
Groovy 演算子オーバロード http://groovy-lang.org/operators.html#Operator-Overloading
GVM http://gvmtool.net/
GroovyServ http://kobo.github.io/groovyserv/
GExcelAPI https://github.com/nobeans/gexcelapi
NekoHTML http://nekohtml.sourceforge.net/
jsoup http://jsoup.org/
プログラミングGROOVY別冊:第8章 Groovy 2.0の新機能
http://beta.mybetabook.com/showpage/506162510cf2ffb79bb046b1
実用的なGroovy: JavaアプリケーションにGroovyを混ぜ込む
http://www.ibm.com/developerworks/jp/java/library/j-pg05245/
Embedding Groovy(JavaからGroovyを使う)
http://groovy.codehaus.org/Embedding+Groovy
Groovyの使いどころ~7つの導入パターン~ http://www.slideshare.net/nobeans/the-report-of-javaone2011-about-groovy
![Page 144: Java開発の強力な相棒として今すぐ使えるGroovy](https://reader033.fdocuments.net/reader033/viewer/2022052311/55a677071a28abb1758b4618/html5/thumbnails/144.jpg)
Java開発の強力な相棒として今すぐ使えるGroovy
Yasuharu Nakano / @nobeans2015-04-11 JJUG CCC 2015 Spring #ccc_g6