Groovyでハマった事 - その1

その1じゃない気がするけど(゚ε゚)キニシナイ!!

GroovyにてFoo.groovyというファイルにて下記コードを記述するとコンパイルエラーになります。

print "tes"    //スクリプトコードとして記述

class Foo{   //ファイル名と同名のクラスを定義
    def name
}

最初これがなんでエラーになるのか全然わからなくてウンウンうなってたんでよねぇ〜
「えっ??Groovyだとクラス定義とスクリプトと同じファイルに記述できないの??」
「いや、でも本にはそんな記述ないし、そもそも『書けるよ!』って書いてあるしな〜」って感じで。

ウンウンうなっているとようやくファイル名と違うクラスなら問題ない事に気づきました。
ということは上記のような場合、内部で定義した場合はインナークラスとして解釈されるのかな?などと思いながらコンパイルされたclassファイルのフォルダを覗いてみると別々にクラスファイルが作成されています。
例えばFooScript.groovyというファイル内にて以下の記述をします。

print "tes"    //スクリプトコードとして記述

class Foo{   //ファイル名と違う名前のクラスを定義
    def name
}

これをプリコンパイルすると「FooScript.class」と「Foo.class」が作成されます。FooScriptが上記で言うスクリプトの部分を担当してるようです。確認はJadを使って逆コンパイルしてみました。というか逆コンパイル後のソースは中々おもしろかったです。興味がある方は是非お試しあれ。

すっきりした気分でGroovyイン・アクションを読み進めてたら7章の所に下記のような記述が ・・・・・・・ !?

Groovyファイルは、クラス宣言とスクリプトのコードを一緒に入れることができる。この場合、スクリプトコードが実行されるメインクラスになる。そのため、宣言するクラスの名前はGroovyソースファイルと同じ名前にしてはならない

・・・・・・・ヽ(`Д´)ノ
まぁ、すぐに気が付かない and いつまでたってもGroovyイン・アクションを読み終わらない自分が悪いんですけどねw
それにハマったおかげで勉強になりましたです。

ついでに以下のような事を試してみました。

  1. NetBeansJavaプロジェクトを作成
  2. 同一パッケージ内にてFoo.groovyとFoo.javaという2つのファイルを作成
  3. プロジェクトをBuildする

結果から言うとGroovyの勝ち?でした*1
これはNetBeansJavaのソースをコンパイルした後にGroovyのソースをプリコンパイルするということでいいのかな??

プリコンパイルモードではなくダイレクトモードだったらどうなるんでしょうね??その辺はGroovyが賢くやってくれたりするんでしょうか。イン・アクションに実は書いてあったりしてww。試してみたいんですがNetBeansだとどうやらGroovyの実行にはプリコンパイルモードしかないようなので断念(このあたりがヘタレですみません(´・ω・`)

*1:生成されたclassファイルを逆コンパイルしたソースで確認しました