web-dev-qa-db-ja.com

androidの列挙型の操作

アプリのAndroidで作業している計算アクティビティはほぼ完了しました。 Gender Enumを作成しようとしましたが、何らかの理由で構文エラー、「EnumBody」を挿入してEnumDeclarationを完了します。

public static enum Gender
{
    static
    {
        Female = new Gender("Female", 1);
        Gender[] arrayOfGender = new Gender[2];
        arrayOfGender[0] = Male;
        arrayOfGender[1] = Female;
        ENUM$VALUES = arrayOfGender;
    }
}

静的{}なしでも試しましたが、同じ構文エラーが発生します。

112
JMSDEV

この構文はどこで見つけましたか? Java列挙型は非常に単純で、値を指定するだけです。

public enum Gender {
   MALE,
   FEMALE
}

より複雑にしたい場合は、このように値を追加できます。

public enum Gender {
    MALE("Male", 0),
    FEMALE("Female", 1);

    private String stringValue;
    private int intValue;
    private Gender(String toString, int value) {
        stringValue = toString;
        intValue = value;
    }

    @Override
    public String toString() {
        return stringValue;
    }
}

次に、enumを使用するには、次のようにします。

Gender me = Gender.MALE
322
Spidy

この競合点については議論がありましたが、最近のドキュメントでさえAndroidはAndroidアプリケーションで列挙型を使用するのはあまり良い考えではないと示唆しています。理由は、静的定数変数よりも多くのメモリを消費するためです。 Androidアプリケーションでの列挙の使用を推奨しない2014年のページのドキュメントを次に示します。 http://developer.Android.com/training/articles/memory.html#Overhead

引用:

メモリのオーバーヘッドに注意してください

使用している言語とライブラリのコストとオーバーヘッドについて十分に理解し、アプリを最初から最後まで設計するときにこの情報を念頭に置いてください。多くの場合、表面上で無害に見えるものは、実際には大量のオーバーヘッドを持っている場合があります。例は次のとおりです。

  • Enumは多くの場合、静的定数の2倍以上のメモリを必要とします。 Androidでは列挙型の使用を厳密に避ける必要があります。

  • Javaのすべてのクラス(匿名の内部クラスを含む)は、約500バイトのコードを使用します。

  • すべてのクラスインスタンスには、12〜16バイトのRAMオーバーヘッドがあります。

  • 単一のエントリをHashMapに入れるには、32バイトかかる追加のエントリオブジェクトを割り当てる必要があります(最適化されたデータコンテナについては前のセクションを参照)。

数バイトがあちこちに追加されます。クラスまたはオブジェクトが重いアプリケーションの設計は、このオーバーヘッドの影響を受けます。そのため、ヒープ分析を見て、RAMを使い果たす小さなオブジェクトがたくさんあるという問題に気付くという難しい立場に置かれる可能性があります。

これらのヒントは時代遅れであり、もはや価値がないと彼らは言うところがいくつかありましたが、彼らがそれを繰り返し続ける理由は、それに対する何らかの真実があるに違いありません。 Androidアプリケーションの作成は、ユーザーエクスペリエンスをスムーズにするために、できる限り軽量に保つ必要があるものです。そして、パフォーマンスのほんの少しずつが重要です!

48
Chris

Chrisがコメントしたように、enumはAndroidにより多くのメモリを必要とします。代わりに IntDef または StringDef を試してください。これらは注釈を使用して、コンパイラが渡された値を検証するようにします。

public abstract class ActionBar {
...
@IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS})
@Retention(RetentionPolicy.SOURCE)
public @interface NavigationMode {}

public static final int NAVIGATION_MODE_STANDARD = 0;
public static final int NAVIGATION_MODE_LIST = 1;
public static final int NAVIGATION_MODE_TABS = 2;

@NavigationMode
public abstract int getNavigationMode();

public abstract void setNavigationMode(@NavigationMode int mode);

また、フラグとして使用して、バイナリ合成(OR/AND演算)を行うこともできます。

EDIT:enumをintに変換するのは Proguardのデフォルトの最適化の1つ のようです。

21
Nacho Coloma
public enum Gender {
    MALE,
    FEMALE
}
17
Gabriel Negut

これによると Video ProGuardを使用する場合、Enumのパフォーマンスの問題について考える必要さえありません!!

多くの場合、ProguardはEnumをINTの値に最適化できるため、実際にそれについて考えたり作業をしたりする必要はありません。

8
Hani

Androidの推奨アプローチは、@ IntDefで強制されるint定数です。

public static final int GENDER_MALE = 1;
public static final int GENDER_FEMALE = 2;

@Retention(RetentionPolicy.SOURCE)
@IntDef ({GENDER_MALE, GENDER_FEMALE})
public @interface Gender{}

// Example usage...
void exampleFunc(@Gender int gender) {
  switch(gender) {
  case GENDER_MALE:

     break;
  case GENDER_FEMALE:
     // TODO
     break;
  }
}

ドキュメント: https://developer.Android.com/studio/write/annotations.html#enum-annotations

3
Anm