1. ホーム
  2. java

[解決済み] Androidでenumを使うのは避けた方が良いですか?

2023-02-10 14:42:29

質問

私は以前、次のような関連する定数のセットを定義していました。 Bundle のような関連する定数をまとめて定義し、以下のようなインターフェースにしていました。

public interface From{
    String LOGIN_SCREEN = "LoginSCreen";
    String NOTIFICATION = "Notification";
    String WIDGET = "widget";
}

これは、関連する定数をまとめて静的import(implementsではない)することで、より良い方法を提供してくれています。私が知っているのは Android フレームワークでも同じように Toast.LENTH_LONG , View.GONE .

しかし、よく感じるのは Java Enums は定数を表現するためのより良い、強力な方法を提供します。

を使うのはパフォーマンス的に問題があるのでしょうか? enumsAndroid ?

少し調べてみると、結局は混乱に陥りました。この質問から Androidのパフォーマンスのヒントから「Intsしか必要としないEnumを避ける」が削除されましたか? を見ると、明らかに Google が削除されたのは明らかです。 "Avoid enums" をパフォーマンスのヒントから削除しましたが、公式トレーニングのドキュメントからは メモリのオーバーヘッドに注意する のセクションには、はっきりとこう書かれています。 enum は、しばしば静的定数の 2 倍以上のメモリを必要とします。Android では、列挙型の使用は厳に避けるべきです。 これはまだ有効なのでしょうか?(例えば Java のバージョン1.6以降)

もう一つ私が観察した問題は enums を横切って intents を使って Bundle シリアライズして送信する必要があります (つまり putSerializable() というのは、プリミティブな操作と比較すると、高価な操作だと思います。 putString() メソッドに比べれば enums はそれを無料で提供しますが)。

で同じものを表現するのに最適な方法はどれなのか、どなたか明確にしていただけませんか? Android ? を使うのは厳に避けるべきでしょうか? enums の上に Android ?

どのように解決するのですか?

使用方法 enum の機能が必要なときに使います。 避けるべきではありません。 厳しく .

Java enumの方が強力ですが、その機能を必要としないのであれば、定数を使うのが良いでしょう。

enumを使うべきとき。

  • 型チェック - 入力に だけ にリストされた値のみを受け入れることができ、それらは連続したものではありません (以下に私が 連続的 を参照してください)。
  • メソッドのオーバーロード - すべての列挙型定数は、メソッドの独自の実装を持ちます。

    public enum UnitConverter{
        METERS{
            @Override
            public double toMiles(final double meters){
                return meters * 0.00062137D;
            }
    
            @Override
            public double toMeters(final double meters){
                return meters;
            }
        },
        MILES{
            @Override
            public double toMiles(final double miles){
                return miles;
            }
    
            @Override
            public double toMeters(final double miles){
                return miles / 0.00062137D;
            }
        };
    
        public abstract double toMiles(double unit);
        public abstract double toMeters(double unit);
    }
    
    
  • より多くのデータ - あなたの1つの定数は、1つの変数に入れることができない複数の情報を含んでいます。

  • 複雑なデータ - 定数がデータを操作するためのメソッドを必要とします。

いつ ではなく を使用します。

  • 1つの型のすべての値を受け入れることができ、定数には最もよく使われるこれらの値のみが含まれます。
  • 連続したデータを受け取ることができます。

    public class Month{
        public static final int JANUARY = 1;
        public static final int FEBRUARY = 2;
        public static final int MARCH = 3;
        ...
    
        public static String getName(final int month){
            if(month <= 0 || month > 12){
                throw new IllegalArgumentException("Invalid month number: " + month);
            }
    
            ...
        }
    }
    
    
  • 名前の場合 (あなたの例のように)
  • enum を必要としない他のすべてのもの。

列挙型はより多くのスペースを占有する

  • 列挙型定数への単一の参照は 4 バイト
  • すべての列挙型定数は、以下のような空間を占めます。 そのフィールドのサイズの合計 8 バイトに整列し オブジェクトのオーバーヘッド
  • enum クラス自体がある程度のスペースを占有しています。

定数はより少ないスペースしか占めません

  • 定数は参照を持たないので、純粋なデータです (たとえ参照であっても、enum インスタンスは別の参照への参照となります)。
  • 定数は既存のクラスに追加することができます - 別のクラスを追加する必要はありません。
  • 定数はインライン化することができます。これにより、コンパイル時の機能が拡張されます。