Bekerja dengan Enums di android

120

Saya hampir selesai dengan aktivitas perhitungan yang saya kerjakan di android untuk aplikasi saya. Saya mencoba untuk membuat Enum Gender, tetapi untuk beberapa alasan mendapatkan kesalahan Sintaks, masukkan "EnumBody" untuk menyelesaikan 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;
    }
}

Saya juga mencobanya tanpa {} statis tetapi saya mendapatkan kesalahan sintaks yang sama.

JMSDEV
sumber
Enum tidak direkomendasikan untuk masalah performa, gunakan konstanta primitif sebagai gantinya. youtube.com/watch?v=Hzs6OBcvNQE
Myke Dev
UPDATE 2019: Enum dapat digunakan di Android karena ART menggantikan DALVIK sebagai lingkungan runtime stackoverflow.com/a/56296746/4213436 . Oleh karena itu saya pikir sebagian besar jawaban di utas ini tidak relevan.
JDenais
@JDenais tentu saja maksud Anda utas 'Anda' baru saja direferensikan
YoussefDir

Jawaban:

343

Di mana Anda menemukan sintaks ini? Java Enums sangat sederhana, Anda tinggal menentukan nilainya.

public enum Gender {
   MALE,
   FEMALE
}

Jika Anda ingin lebih kompleks, Anda dapat menambahkan nilai seperti ini.

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

Kemudian untuk menggunakan enum, Anda akan melakukan sesuatu seperti ini:

Gender me = Gender.MALE
Rapi
sumber
12
Saya akan mencobanya, saya memang bilang saya benar-benar pemula
JMSDEV
87
Maaf, saya tidak bermaksud negatif. Hanya sintaks paling aneh yang pernah saya lihat untuk Enum
Spidy
4
Ini juga membantu untuk menyebutkan enum berurutan sehingga Anda bisa menggunakan .ordinal () pada enum untuk mendapatkan nilai int.
Kalel Wade
1
Sintaks dalam pertanyaan adalah jenis yang mungkin dihasilkan dari penggunaan decompiler.
Dan Getz
9
Saya tertawa terbahak-bahak pada "Di mana Anda menemukan sintaks ini". Mengatakan seperti seorang guru kepada muridnya
Zar E Ahmer
50

Ada beberapa perdebatan seputar hal ini, tetapi bahkan dalam dokumen terbaru android menyarankan bahwa menggunakan enum dalam aplikasi android bukanlah ide yang bagus. Alasannya adalah karena mereka menggunakan lebih banyak memori daripada variabel konstanta statis. Berikut adalah dokumen dari halaman 2014 yang menyarankan agar tidak menggunakan enum dalam aplikasi android. http://developer.android.com/training/articles/memory.html#Overhead

Saya mengutip:

Waspadai overhead memori

Pahami tentang biaya dan overhead bahasa dan pustaka yang Anda gunakan, dan ingatlah informasi ini saat Anda mendesain aplikasi Anda, dari awal hingga akhir. Seringkali, hal-hal di permukaan yang terlihat tidak berbahaya sebenarnya memiliki biaya overhead yang besar. Contohnya termasuk:

  • Enum sering kali membutuhkan lebih dari dua kali lebih banyak memori sebagai konstanta statis. Anda harus benar-benar menghindari penggunaan enum di Android.

  • Setiap kelas di Java (termasuk kelas dalam anonim) menggunakan sekitar 500 byte kode.

  • Setiap instance kelas memiliki overhead RAM 12-16 byte.

  • Menempatkan satu entri ke dalam HashMap memerlukan alokasi objek entri tambahan yang membutuhkan 32 byte (lihat bagian sebelumnya tentang wadah data yang dioptimalkan).

Beberapa byte di sana-sini dengan cepat bertambah — desain aplikasi yang berkelas atau berat objek akan menderita akibat overhead ini. Itu dapat membuat Anda berada dalam posisi sulit untuk melihat analisis heap dan menyadari bahwa masalah Anda adalah banyak objek kecil yang menggunakan RAM Anda.

Ada beberapa tempat di mana mereka mengatakan bahwa tips ini sudah ketinggalan zaman dan tidak lagi berharga, tetapi alasan mereka terus mengulanginya, pasti ada benarnya. Menulis aplikasi android adalah sesuatu yang harus Anda jaga seringan mungkin untuk pengalaman pengguna yang lancar. Dan setiap inci kinerja sangat berarti!

Chris
sumber
Ada beberapa tempat - dapatkah Anda menambahkan beberapa jika Anda mengetahuinya? karena saya tidak dapat menemukan
Krzysztof Skrzynecki
9
Di sini seseorang memperhatikan bahwa informasi tentang penggunaan int dan bukan enum telah dihapus dari Performance Tip dalam dokumentasi resmi. Selain itu, saya telah membuat penelitian dan memposting ringkasan di reddit
Krzysztof Skrzynecki
1
Pola Kinerja Android: Harga ENUM (100 Hari Google Dev)
Afriza N. Arief
Teman-teman, pertanyaan saya adalah jika Enum adalah praktik yang "buruk", mengapa Google masih mendukung fitur Java ini dengan Android? :(
Jesús Castro
5
@ JesúsCastro Karena Google ingin memastikan bahwa perusahaan dengan banyak logika bisnis Java yang ada (yang mungkin menggunakan enum) dapat meletakkan pustaka mereka ke dalam proyek Android dan pergi.
David Brown
22

Seperti yang dikomentari oleh Chris, enum membutuhkan lebih banyak memori di Android yang bertambah saat mereka terus digunakan di mana-mana. Anda harus mencoba IntDef atau StringDef , yang menggunakan anotasi sehingga compiler memvalidasi nilai yang diteruskan.

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

Ini juga dapat digunakan sebagai flag, memungkinkan komposisi biner (operasi OR / AND).

EDIT : Tampaknya mengubah enum menjadi int adalah salah satu pengoptimalan default di Proguard .

Nacho Coloma
sumber
3
Saya suka menempatkan konstanta int langsung ke kelas anotasi. Jadi ini terlihat seperti enum biasa. Saya menjelaskannya di sini: blog.shamanland.com/2016/02/int-string-enum.html
Oleksii K.
17
public enum Gender {
    MALE,
    FEMALE
}
Gabriel Negut
sumber
9

Menurut Video ini jika Anda menggunakan ProGuard, Anda bahkan tidak perlu memikirkan masalah kinerja Enum !!

Proguard dalam banyak situasi dapat mengoptimalkan nilai Enums ke INT atas nama Anda sehingga Anda tidak perlu memikirkannya atau melakukan pekerjaan apa pun.

Hani
sumber
4

Pendekatan yang disukai Android adalah konstanta int yang diberlakukan dengan @IntDef:

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

Dokumen: https://developer.android.com/studio/write/annotations.html#enum-annotations

Anm
sumber