0
1

More than 1 year has passed since last update.

@IntDefについて

Last updated at Posted at 2021-10-18

経緯

私はEnumクラスが大好きなのですが、この前初めてIntDefを触りました。
独自アノテーションに対して付与する・・・?
便利そうなので調べてみました。

IntDef(StringDef)とは

端的に言うと、AndroidにおいてEnumより軽く、型安全に定数を使用できるようになるアノテーションのことです。

Enumを使用した場合、1つのEunmにつき1.0~1.4 KB ほど増えることがあるそうです。
サイズの増加は可能な限り避けたいので、かなり有用な方法に思えます。(参考

使ってみる

とりあえずEnumのサンプルを。細かい部分は目を瞑ってください。

Sample.java
    public enum DayOfTheWeek {
        SUNDAY,        
        MONDAY,
        TUESDAY,
        WEDNESDAY,
        THURSDAY,
        FRIDAY,
        SATURDAY
    }

    public String getJPNName(DayOfTheWeek dayOfTheWeek){
        // 和名を返す
    }

Enumを使わないとしたら、定数で定義していく感じですかね。

Sample.java
    public static final int SUNDAY = 0;
    public static final int MONDAY = 1;
    public static final int TUESDAY = 2;
    public static final int WEDNESDAY = 3;
    public static final int THURSDAY = 4;
    public static final int FRIDAY = 5;
    public static final int SATURDAY = 6;

    public String getJPNName(int dayOfTheWeek){
        // 和名を返す
    }

この場合はgetJPNNameメソッドがintを受けるので、意図しない値が渡ってくるかもしれません。

そこでIntDefの出番です。
(見やすさを優先し@Retentionは付与していませんが、公式にもついているので付与した方が良いと思います。アノテーションの読み込みタイミングを指定できるものだそうです。参考

Sample.java
    @IntDef({SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY})
    public @interface DayOfTheWeek {
    }

    public static final int SUNDAY = 0;
    public static final int MONDAY = 1;
    public static final int TUESDAY = 2;
    public static final int WEDNESDAY = 3;
    public static final int THURSDAY = 4;
    public static final int FRIDAY = 5;
    public static final int SATURDAY = 6;

    public String getJPNName(@DayOfTheWeek int dayOfTheWeek) {
        // 和名を返す
    }

上記のように書くと利用する際に警告を出してくれます。
スクリーンショット 2021-10-18 11.32.11.png

また、てきとうな値を入れると候補を出してくれます。
スクリーンショット 2021-10-18 11.32.57.png

非常に便利です。ただし、ビルドは通ってしまうのでそこだけ注意ですね。

ちなみにLongDef、StringDefというものもあります。

kotlinの場合

先ほどはJavaで定義しkotlinから呼び出しました。
なぜkotlinで定義しなかったかというと、IntDefアノテーションによるチェックがうまく働いてくれないためです。

Sample2.kt
    companion object {
        const val SUNDAY = 0
        const val MONDAY = 1
        const val TUESDAY = 2
        const val WEDNESDAY = 3
        const val THURSDAY = 4
        const val FRIDAY = 5
        const val SATURDAY = 6
    }

    @IntDef(SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY)
    annotation class DayOfTheWeek

    fun getJPNName(@DayOfTheWeek dayOfTheWeek: Int): String {
        // 和名にして返す
    }

先ほどと同じ方法で利用してみます。

スクリーンショット 2021-10-18 11.33.47.png

スクリーンショット 2021-10-18 11.34.02.png
なにも出ていません。

これでは逆に不便ですね。
一応コードを読めばどういう値を求めているのかはわかりますが、型安全ではないです。
現状Enumを使うしかないのかもしれません。強固に検査するのも手でしょうか・・・。

終わりに

IntDef自体は随分前からあったのに最近知ったのがショックでした。
勉強不足露呈ですね。
私は現在メイン言語がkotlinなので、知ったとてうまく動かないことも残念です。
なにか良い方法がないか模索していこうと思います。

0
1
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
0
1