Groovy とは
Java 上で動作するスクリプト言語のこと。
Java に必要な機能を追加した結果とのこと。
Groovy クイックインストール
Windows の場合
- 無ければ JDK (Java SE Development Kit) をインストールする。
- groovyのサイト からインストーラをダウンロードする。 記載当時 Groovy 2.4 が最新の安定版だった。
- インストーラを実行する。
- もし Groovy の環境変数が PATH に見つからない場合は追加する。(アンインストーラはこの情報を削除しない) JAVA_HOME が未設定だと警告が出る。これがないと Groovy が正常に動作しない。 もし警告が出たら JDK をインストールしていない可能性があるので確認すること。
- スタートメニューに「Start GroovyConsole」が表示されたらインストール完了。
Hello Groovy World
- Start GroovyConsole を起動する。
- 画面上部(スクリプト記述エリア)に次のスクリプトを記載する。
println("HelloWorld");
- Execute GroovyScriptボタンを押すか、Ctrl+Rを押してスクリプトを実行する。
- 画面下部に実行結果としてHelloWorldが表示されたら成功。
GUI(AWTのFrame)も試してみる。下記はHelloGroovyWorld(AWT)の実行画面。
/* Hello World (GUI) スクリプト */
import java.awt.*;
import java.awt.event.*;
/**
* MainFrame クラス
*/
class MainFrame extends Frame
{
def _menuBar;
def _labelBody;
/**
* コンストラクタ
*/
MainFrame() {
/* タイトルを初期化 */
setTitle("Hello World")
/* メニューを初期化 */
_menuBar = new MenuBar();
def _menu = new Menu("ファイル");
def _menuItem = new MenuItem("閉じる");
_menuItem.addActionListener(new java.awt.event.ActionListener()
{
public void actionPerformed(ActionEvent e) {
closeFrame(e);
}
});
_menu.add(_menuItem);
_menuBar.add(_menu);
setMenuBar(_menuBar);
/* フレーム内表示コンテンツを初期化 */
_labelBody = new Label("Hello World");
this.add(_labelBody);
/* サイズを初期化 */
setSize(new Dimension(300, 200));
}
/* フレームクローズ操作 */
def closeFrame(e)
{
this.dispose();
}
}
/* エントリポイント */
new MainFrame().show();
Java に対する Groovy の特徴
参考情報:Apache Groovy - Differences with Java
参考情報:Code Zine - Groovyってどんな言語?
JavaプログラマのためのGroovy入門
- 一般的に利用する機会の多いクラスパッケージのいくつかがデフォルトでimportされているため宣言せず利用できる。
- java.io.*, java.lang.*, java.math.BigDecimal, java.math.BigInteger, java.net.*, java.util.*, groovy.lang.*, groovy.util.*
- マルチメソッド(又はランタイムディスパッチ)により、メソッド名と返値の型が同一で、引数の型が異なるメソッドが定義できる。これらは、実行時に与えた引数の型に応じて実行するメソッドが選択される。※どういったケースで便利なのかいまいち分からない。
- クロージャが使える。
- クロージャは引数を取ることが出来る。引数は暗黙的に仮引数itで表される。明示的に指定することも可能。
clodure = { println("${it}が渡された。"); }; clodure("テスト");
、clodure = { name,age -> println("${name}は${age}才です。"); }; clodure("Alice",10);
- クロージャは引数として指定できる。そのため each メソッドなどの引数に与えることで、制御構文を使わず配列の全要素へのアクセスが簡単に記述できる。
sum = 0; (1..10).each { sum += it }; println(sum);
- クロージャは宣言されたクラスの変数へアクセスできる。そのため、イベント駆動動作を容易に定義できる。
- クロージャは引数を取ることが出来る。引数は暗黙的に仮引数itで表される。明示的に指定することも可能。
- 配列の初期化書式が異なる。(クロージャにより {} が予約されているため)
int[] array = [1,2,3];
- 変数定義時のアクセス制御子を省略した際は private フィールドと認識され、Getter/Setter が自動定義される。また、パッケージ内で有効な package-private として定義する場合は、@PackageScope を記載する。(private と書かれているが、アクセス制御されていない様子)
- Getter/Setter のメソッド名は
getXXX()
,setXXX()
となる。※コンパイル時に自分が宣言していないメソッド名でエラーとなる場合はこの動作が原因である可能性がある。
- Getter/Setter のメソッド名は
- Automatic Resource Management (ARM) は使えない。同等の処理はクロージャを使って処理できる。
new File('C:\\path\\to\\file.txt').eachLine('Shift-JIS'){ println it; }
- 匿名内部クラスの動作は Java の指針に従うものの挙動は異なる。詳細は Groovy の Documentation を参照のこと。
- Java 8 で定義されたラムダ式は匿名内部クラスとして認識できるが、Groovy ではシンタックスエラーとなる。代わりにクロージャを使うこと。
- ダブルクオートで括られた文字列リテラルは GString 型の値として処理される。
- シングルクオートで括られた文字列リテラルは明示的に char で宣言されない限り String 型として処理される。2 文字以上の文字列を char としてキャストすると最初の 1 文字だけの char として処理される。
- データ型は Object として認識され、プリミティブ型等へのオートラップされるため、widening/narrowing 変換処理の結果と異なることがある。
- 比較演算子
==
の挙動が Java ではプロミティブ型の比較だが、Groovy ではa.compareTo(b)==0
またはa.equals(b)
に置き換えられる。同一性を確認するためにはa.is(b)
を使う。 - Groovy における暗黙の型変換の挙動は Java と異なる。詳細はGroovy の Documentation を参照のこと。
他、as, def, in, trait がある。(予約文字)
Java と比べてソースコードの記述ルールが緩い(Strictの逆)。例えば、行末のコロンは不要であり、データ型を宣言しなくてよい。また、どのクラスにも属さない文を記述することができる。(ルーズステートメント)
def で変数を宣言すると、変数に代入された値に応じた適切な型を動的に変更する。
マップ型が利用できる。
map = ["Alice":10, "Bob":20, "Charlie":30]; println(map["Alice"]);
制御構文では暗黙で評価結果が 0 や null ならば false、他は true となる。
switch文は数値以外を評価してcase分けできる。
for文の書式が異なる。
for (m in list) { print m.toString(); };
クラス定義の動的変更(Expando)機能が用意されている。
def e = new Expando(); e.msg = "Hello World"; e.show = { println(msg); }; e.show();
java.sql パッケージにより SQL クエリ処理が楽に記述できる。
Builder により HTML/XML/Swing 等の構造化されたデータが簡単に記述できる。
import groovy.xml.MarkupBuilder; new MarkupBuilder().html { body { div { mkp.yield( 'Hello World' ) }; div( style:'style.css' ) { mkp.yield('Groovy') } } }