LoginSignup
1
2

More than 1 year has passed since last update.

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

Last updated at Posted at 2021-08-01

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

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");
    }

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

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2