2017年1月22日日曜日

Groovy / Differences with Java

Groovyの公式ドキュメントを読んでみます。
参考:Differences with Java

実行環境:Groovy Version: 2.4.8 JVM: 1.8.0_111 IDE:IntelliJ IDEA 2016.3.3


Default imports

次のパッケージはデフォルトでインポートされていますので、
下記のパッケージのクラスは明示的にimportしなくても使えます。

  • java.io.*
  • java.lang.*
  • java.math.BigDecimal
  • java.math.BigInteger
  • java.net.*
  • java.util.*
  • groovy.lang.*
  • groovy.util.*
printlnで標準出力できます〜。(System.outがいらない)


Intellij IDE CEでJunitしてみる

プロジェクトを右クリックする
Open Module Settings
Libraries
+ button
Junitで検索
とりあえず現在の最新のjunit:junit:4.12を検索
OK

あとは実行クラスでassertするだけ

import org.junit.Assert;
Assert.assert();


Intellij IDE CEでgroovyしてみる

Groovyプロジェクトは最初から選べましたが、
実行してみるとSDKがないと怒られました。

実行環境がMax OSXなので、brew install groovysdkです。
先にgroovyだけでインストールしていると競合します。
(エラーメッセージにある通り、brew unlink groovy競合を回避できます)

...

が、しかし、
brewでのインストール先が、「/usr/local/Cellar/groovysdk/2.4.7」で
Intellijで選べないとこにあるわけです。
しょうがないので、公式からzipをダウンロードし、解凍したディレクトリを選択します。
これでコンパイルできます。


Multi-method(Runtime Dispatch)

オーバーロードされたメソッドについての話。
Javaだとコンパイル時にどのメソッドを呼ぶかが決まります。
一方、実行時の引数の型により、呼び出すメソッドが決まります。

公式のサンプルをIntelliJで実行できる形式にしたものが下記です。
※JUnitをライブラリに登録してあるものとします。

import org.junit.Assert;

int test(String arg) {
    return 1;
}
int test(Object arg) {
    return 2;
}
Object o = "Object";
int returnInt = test(o);

//println result;
Assert.assertEquals((long)1, (long)returnInt);


IntelliJの実行ショートカット

Ctl + Shift + r
MacでIntelliJを使うのに慣れていないものでして。。。

Array initializers

配列の初期化は[]でよろしくどうぞ。
{}はクロージャ(無名メソッド)で予約されているので、配列の初期化には使えないそうです。

unexpected token: 1 @ line 4, column 17.
   int[] array = { 1, 2, 3};
                   ^
こんな感じで怒られます。

クラスのフィールドのアクセス修飾子を省力するとprivateとなりgetter/setterが作られます

class Student {
    String name
}

Student person = new Student()
person.setName("hoge")

println(person.getName())
Javaだとデフォルトのアクセスレベルはパッケージプライベートです。

また、groovyで@PackageScopeアノテーションをつけることで、
パブリックではなく、パッケージプライベートにすることができるようです。
自分の環境だと下記のエラーでアノテーションとして認識してくれなかったのですが。。。

6: unable to resolve class PackageScope ,  unable to find class for annotation
 @ line 6, column 1.
   @PackageScope class Student {
コマンドラインで実行してもダメ、コンパイルの設定も問題なさそうでしたが。。。
stackoverflowでも同じ事例はなさそうで、
「Eclipseでクリーン実行したらエラーが消えた」という事例はありましたがIntelliJでクリーン実行なさげ。


EclipseでGroovyしてみる

上記のunable to resolve class PackageScope問題で、原因切り分けとして、
Eclipseで同じコードを実行してみます。
参考:Qiita Gradle + Spock + Eclipse環境
まずプラグインが入っていなかったので、入れます。
使用バージョンは、STS 3.8.3.RELEASE(Eclipse Neon.2(4.6.2))です。
Help → Install New Software... →
http://dist.springsource.org/snapshot/GRECLIPSE/e4.6/ に対して、groovyで検索してプラグインを入れます。
これで新規作成ウィザードでGroovy関連を使用できます。
結果、変わらず「PackageScope is not an annotation」でエラーでした。とりあえず次。


GroovyはTry with Resourceをサポートしていません

公式でARM(Automatic Resource Management)という言葉が出てきましたが、StackOverflowを見た限り、
Try with ResourceのことをARMとも呼ぶみたいです。
GroovyはTry with Resourceはサポートしていませんが、クロージャで代用することが可能みたいです。
該当するeachLineメソッドがドキュメントに載っていないので、定かではないのですが。。。
IOGroovyMethodsのpublic static <T> T eachLine(InputStream stream, Closure<T> closure)
が一番近しいですが、、、どうだか。


Static inner classes

若干Javaと異なるらしい

Static inner classes

これは全然変わらない。

Anonymous Inner Classes

インナークラスのインスタンス生成は、
outer.new.Inner()はサポートされず、new Outer(inner)で書く


Lambdas

Java8のラムダそのままの書き方ができないが、クロージャで代用できる。


GStrings

ダブルクォートで囲った文字列は、GStringとして解釈される。
ダラーマークを含む文字列が,JavaとGroovyで若干異なる出力になる可能性がある。
ただ、Java APIに沿ってGStringとStringをオートキャストしてくれる。
しかし、Objectクラスの場合は、実際の値がチェックされる。


String and Character literals

Groovyだとシングルクォートは文字列として扱われる。
char型の変数にシングルクォートの値が割り振られた時は、自動でcharにキャストする。
値を直接参照する時は、キャストされないので、明示的にキャストする必要がある。

キャスト方法

  1. (char)'a'
  2. 'a' as char
(char)'a'
String str = 'x'
char x = (char) str
println((Object)x.getClass().getCanonicalName())
println(x)
-----------
java.lang.Character
x
'a' as char
String str = 'x'
char x = str as char
println((Object)x.getClass().getCanonicalName())
println(x)
-----------
java.lang.Character
x


Primitives and wrappers

Groovyは変数を全てオブジェクトとして扱う、とさらっと書かれています。
そのため、プリミティブ型変数をラッパークラスに自動変換します。
Javaはボクシング(ラッパークラスからプリミティブ型変数への変換)より変数拡張を優先します。
Groovyでは、プリミティブ型変数の引数をラッパークラスとしてまずは扱うので、
JavaとGroovyとでオーバーライドしたメソッドの呼び出し先が異なる場合があります。


Behaviour of ==

==:値のチェック
a.is(b):参照のチェック
nullは==でいいみたいです。


Extra keywords

Javaのキーワードに加えて、Groovyはas, def, in, traitもキーワードです。


Conversions

時間があるときに、確認します。


参照サイト

公式以外はこれかな、、、
http://www.tutorialspoint.com/groovy/

1 件のコメント:

  1. おはようございます。

    groovy、使ってみたいですね!

    返信削除