JavaにGroovy混ぜてみた
前回の円周率の件でちょっと気になったので実験してみた。
何の実験かと言えば,「Groovyで改変したJavaのクラスの有効範囲の確認」。GroovyClassLoaderの仕様うんぬんについては,「Groovyイン・アクション(asin:4839927278)」に書いてあったはずなんで,ホンキで取り組むときは観念して購入しよう。:-)
結論から言えば,Groovyで改変した操作はGroovyの中でのみ有効。この結論は予想してたけど,Groovy内で生成したJavaのインスタンスに関しても同様だったのが,「へぇ,そうなんだー」的な結果だった。
以下,そのレポート。
こんなコールグラフになるクラス群を作ってだね(J1, J2はJava。G1, G2はGroovy)。G1.first()でBigDecimalの+演算子をオーバロードしてみたよ。
すげー雑でゴメンなソースを文末に晒すんで,とりあえず実行結果だけ張っつけとくよ。
20 20.0 ! 30.0 20 ! 30.0 ! 60.0 20 10
こっからソースコード。
--- J1.java --- import java.math.BigDecimal; public class J1 { public static void main(String[] args) { BigDecimal b1 = new BigDecimal(10); BigDecimal b2 = new BigDecimal(10); System.out.println(b1.add(b2)); G1.first(); f(); G1.second(); G2.doit(); } public static void f() { BigDecimal b1 = new BigDecimal(10); BigDecimal b2 = new BigDecimal(10); System.out.println(b1.add(b2)); } } --- J2.java --- import java.math.BigDecimal; public class J2 { public J2() { BigDecimal b1 = new BigDecimal(5); BigDecimal b2 = new BigDecimal(5); System.out.println(b1.add(b2)); } }
--- G1.groovy --- class G1 { static void first() { println 10.0 + 10.0 BigDecimal.metaClass.plus = { BigDecimal x -> print "! " delegate.add(x*2) } println 10.0 + 10.0 } static void second() { println 10.0 + 10.0 } } --- G2.groovy --- class G2 { static void doit() { println 20.0 + 20.0 J1.f() new J2() } }
ps.
どうでもいいが,IntelliJのCodeExplorerプラグインがGroovyのコードまで追跡してて感動した。
プラグインのデキもさることながら,そんだけPSIが言語問わずに抽象化されたんだなぁとも想像したよ。