@IntDef

定数を使う場合、予期せぬ値が代入される可能性があるため型安全ではない。
しかし、enumはapkのサイズが大きくなるデメリットもある。
そこでAndroidには@IntDefという型安全な定数を定義するアノテーションがある。

IntDef  |  Android Developers
Improving Android: 列挙にはenumではなくIntDef, StringDef annotationを使う - stsnブログ
Activity, Fragment, CustomView の使い分け - マッチョなActivityにさよならする方法 -

build.gradleで、

support-annotationsを追加。
activity_main.xmlは、

TextView1つ。
MainActivity.javaは、

package com.bgstation0.android.sample.annotationintdef_;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    // 列挙型
    public enum THREE{
        FIRST, SECOND, THRID
    }
    
    // 生成時
    @Override
    protected void onCreate(Bundle savedInstanceState) {

        // 既定の処理.
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 値を取得してセット.
        int num = getThree(THREE.SECOND);   // getThreeでSECONDに対応する値を取得.
        TextView textView1 = findViewById(R.id.textview1);   // textViewを取得.
        String text = Integer.toString(num);    // numをtextに変換.
        textView1.setText(text); // textをセット.

    }

    // 引数に合う値を取得.
    int getThree(THREE three){
        if (three == THREE.FIRST){
            return 1;
        }
        else if (three == THREE.SECOND){
            return 2;
        }
        else if (three == THREE.THRID){
            return 3;
        }
        else{
            return -1;
        }
    }

}

SECONDを指定すると、2を返す。
それをTextViewで表示。
まずは、列挙型で試す。

当然2と出る。
当然2と出る。

当然2と出る。

1405KB
1405KB

この時のapkサイズは、1405KB。

package com.bgstation0.android.sample.annotationintdef_;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    // 列挙型
    //public enum THREE{
    //    FIRST, SECOND, THRID
    //}

    // 定数
    static final int FIRST = 1;
    static final int SECOND = 2;
    static final int THIRD = 3;

    // 生成時
    @Override
    protected void onCreate(Bundle savedInstanceState) {

        // 既定の処理.
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 値を取得してセット.
        int num = getThree(SECOND);   // getThreeでSECONDに対応する値を取得.
        TextView textView1 = findViewById(R.id.textview1);   // textViewを取得.
        String text = Integer.toString(num);    // numをtextに変換.
        textView1.setText(text); // textをセット.

    }

    // 引数に合う値を取得.
    int getThree(int three){
        if (three == FIRST){
            return 1;
        }
        else if (three == SECOND){
            return 2;
        }
        else if (three == THIRD){
            return 3;
        }
        else{
            return -1;
        }
    }

}

今度は定数。

1404KBで1KB減った。
1404KBで1KB減った。

1404KBで1KB減った。

最後に@IntDef。
@IntDefに下で定義した定数を指定する。
@Retentionも付けて、独自のアノテーション@Threeを定義。
このアノテーションを関数引数のところに付けると、引数が型安全になる。
わざと10をセットしてみると、

こういう表示が出るので、間違ってるとわかる。
こういう表示が出るので、間違ってるとわかる。

こういう表示が出るので、間違ってるとわかる。

ただビルドは出来てしまう。apkは1KB小さい。
ただビルドは出来てしまう。apkは1KB小さい。

ただビルドは出来てしまう。apkは1KB小さい。

ビルドが通るので実行時は異常であることのエラー
ビルドが通るので実行時は異常であることのエラー

ビルドが通るので実行時は異常であることのエラー。

Sample/android/annotationIntDef/annotationIntDef/src/annotationIntDef at master · bg1bgst333/Sample · GitHub