@JvmStaticと@JvmFieldをobject（またはcompanion object）のフィールドに付与した場合の違いについて

基礎的な部分にはなりますが、一瞬迷ってしまうのでいろんなパターンを試してみました。

## JvmStaticアノテーション
・メソッドに付与すると、INSTANCE・Companionオブジェクトを経由せずアクセスできるようになる。
・フィールドに付与すると、getter/setterを作成してくれる。

## JvmFieldアノテーション
・メソッドに付与はできない。（構文エラーが出ます。）
・フィールドに付与すると、INSTANCE・Companionオブジェクトを経由せずアクセスできるようになる。



## 上記を踏まえて

とりあえず使ってみました。

適当なフィールドを持つクラスを作成。
JvmTestKotlinObject.ktの方はobjectキーワードで定義しているので、それ自体がシングルトン。
JvmTestKotlinClass.ktの方はclassキーワードで定義しcompanion objectを宣言しているので、シングルトンを内包しているクラスです。

``` JvmTestKotlinObject.kt
object JvmTestKotlinObject {
    @JvmStatic
    var varField1: String = ""

    @JvmStatic
    val valField1: String = ""

    @JvmField
    var varField2: String = ""

    @JvmField
    val valField2: String = ""

    const val constValField2 = ""

    var field3: String = ""
}
```

``` JvmTestKotlinClass.kt
class JvmTestKotlinClass {
    companion object {
        @JvmStatic
        var varField1: String = ""

        @JvmStatic
        val valField1: String = ""

        @JvmField
        var varField2: String = ""

        @JvmField
        val valField2: String = ""

        const val constValField2 = ""

        var field3: String = ""
    }
}
```

それらをJavaから見てみる。

まずはJvmTestKotlinObject.kt。

``` JvmTestJava.java
public void testKotlinObject() {
        /** @JVMStatic var **/
        JvmTestKotlinObject.getVarField1();
        JvmTestKotlinObject.setVarField1("hoge");

        /** @JVMStatic val **/
        JvmTestKotlinObject.getValField1();
        // これはだめ。
        //JvmTestKotlinObject.setValFIeld1("hoge");

        /** @JVMField var **/
        String varField2 = JvmTestKotlinObject.varField2;
        JvmTestKotlinObject.varField2 = "hoge";

        /** @JVMField val **/
        String valField2 = JvmTestKotlinObject.valField2;
        // これはだめ。
        //JvmTestKotlinObject.valField2 = "hoge";

        /** const **/
        String constValField2 = JvmTestKotlinObject.constValField2;
        // これはだめ。
        //JvmTestKotlinObject.constValField2 = "";

        /** アノテーションなしpublicなプロパティ **/
        // INSTANCEオブジェクト経由ならアクセス可能。 
        JvmTestKotlinObject.INSTANCE.getField3();
        JvmTestKotlinObject.INSTANCE.setField3("hoge");
    }
```

次にJvmTestKotlinClass.kt。

``` JvmTestJava.java
    public void testKotlinClass() {
        /** @JVMStatic var **/
        JvmTestKotlinClass.getVarField1();
        JvmTestKotlinClass.setVarField1("hoge");

        /** @JVMStatic val **/
        JvmTestKotlinClass.getValField1();
        // これはだめ。
        //JvmTestKotlinClass.setValFIeld1("hoge");

        /** @JVMField var **/
        String varField2 = JvmTestKotlinClass.varField2;
        JvmTestKotlinClass.varField2 = "hoge";

        /** @JVMField val **/
        String valField2 = JvmTestKotlinClass.valField2;
        // これはだめ。
        //JvmTestKotlinClass.valField2 = "hoge";

        /** const **/
        String constValField2 = JvmTestKotlinClass.constValField2;
        // これはだめ。
        //JvmTestKotlinClass.constValField2 = "hoge";

        /** アノテーションなしpublicなプロパティ **/
        // INSTANCEオブジェクト経由でもアクセスは不可。
        //JvmTestKotlinClass.INSTANCE.getField3();
        //JvmTestKotlinClass.INSTANCE.setField3("hoge");

        // もちろんこれもだめ。
        //JvmTestKotlinClass.getField3();
        //JvmTestKotlinClass.setField3("hoge");

        // Companionオブジェクト経由ならアクセス可能。
        JvmTestKotlinClass.Companion.getField3();
        JvmTestKotlinClass.Companion.setField3("hoge");
    }
```

アノテーションは便利ですね。