Saya biasa mendefinisikan satu set konstanta terkait seperti Bundle
kunci bersama-sama dalam antarmuka seperti di bawah ini:
public interface From{
String LOGIN_SCREEN = "LoginSCreen";
String NOTIFICATION = "Notification";
String WIDGET = "widget";
}
Ini memberi saya cara yang lebih baik untuk mengelompokkan konstanta terkait dan menggunakannya dengan membuat impor statis (bukan mengimplementasikan). Saya tahu Android
kerangka juga menggunakan konstanta dengan cara yang sama seperti Toast.LENTH_LONG
, View.GONE
.
Namun, saya sering merasa bahwa cara Java Enums
memberikan jauh lebih baik dan ampuh untuk mewakili konstanta.
Tapi apakah ada masalah performence dalam menggunakan enums
on Android
?
Dengan sedikit riset, saya berakhir dalam kebingungan. Dari pertanyaan ini
? "Enum Hindari Dimana Anda Hanya Perlu Ints” dihapus dari tips kinerja Android jelas bahwa Google
telah dihapus 'Hindari enum' dari tips kinerjanya, tapi dari itu docs pelatihan resmi Menyadari overhead memori bagian itu jelas mengatakan: "Enums seringkali membutuhkan lebih dari dua kali lebih banyak memori sebagai konstanta statis. Anda harus benar-benar menghindari penggunaan enum di Android. " Apakah ini masih berlaku? (Katakanlah dalam Java
versi setelah 1.6)
Salah satu isu lagi yang saya amati adalah untuk mengirim enums
seluruh intents
menggunakan Bundle
saya harus mengirim mereka dengan serialisasi (yaitu putSerializable()
, yang saya pikir operasi yang mahal dibandingkan dengan primitif putString()
metode, walaupun enums
menyediakan secara gratis).
Bisakah seseorang menjelaskan cara terbaik untuk mewakili hal yang sama Android
? Haruskah saya benar-benar menghindari penggunaan enums
on Android
?
Enum.ordinal()
.Jawaban:
Gunakan
enum
saat Anda membutuhkan fitur-fiturnya. Jangan menghindarinya dengan ketat .Java enum lebih kuat, tetapi jika Anda tidak membutuhkan fiturnya, gunakan konstanta, mereka menempati lebih sedikit ruang dan mereka bisa menjadi primitif itu sendiri.
Kapan menggunakan enum:
method overloading - setiap konstanta enum memiliki implementasi metode sendiri-sendiri
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); }
lebih banyak data - satu konstanta Anda berisi lebih dari satu informasi yang tidak dapat dimasukkan ke dalam satu variabel
Kapan tidak menggunakan enum:
Anda dapat menerima data berkelanjutan
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 menempati lebih banyak ruang
Konstanta menempati lebih sedikit ruang
sumber
Jika enum hanya memiliki nilai, Anda harus mencoba menggunakan IntDef / StringDef, seperti yang ditunjukkan di sini:
https://developer.android.com/studio/write/annotations.html#enum-annotations
Contoh: alih-alih:
enum NavigationMode {NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST, NAVIGATION_MODE_TABS}
Kau gunakan:
@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;
dan dalam fungsi yang memilikinya sebagai parameter / nilai yang dikembalikan, gunakan:
@NavigationMode public abstract int getNavigationMode(); public abstract void setNavigationMode(@NavigationMode int mode);
Jika enumnya kompleks, gunakan enum. Tidak seburuk itu.
Untuk membandingkan enum vs nilai konstanta, Anda harus membaca di sini:
Contohnya adalah enum dengan 2 nilai. Dibutuhkan 1112 byte dalam file dex dibandingkan dengan 128 byte ketika bilangan bulat konstan digunakan. Masuk akal, karena enum adalah kelas nyata, bukan cara kerjanya di C / C ++.
sumber
IntDef
anotasi, itu akan terjadi. Mengenai jam tangan, menurut saya cukup jelas juga. Perangkat mana yang memiliki lebih banyak daya CPU, RAM, dan baterai: telepon atau jam tangan? Dan mana yang membutuhkan perangkat lunak agar kinerjanya lebih optimal?Selain jawaban sebelumnya, saya akan menambahkan bahwa jika Anda menggunakan Proguard (dan Anda harus melakukannya untuk mengurangi ukuran dan mengaburkan kode Anda), maka Anda
Enums
akan secara otomatis dikonversi ke@IntDef
mana pun memungkinkan:https://www.guardsquare.com/en/proguard/manual/optimizations
Oleh karena itu, jika Anda memiliki beberapa nilai diskrit dan beberapa metode hanya memungkinkan untuk mengambil nilai ini dan bukan yang lain dari jenis yang sama, maka saya akan menggunakan
Enum
, karena Proguard akan membuat manual ini bekerja mengoptimalkan kode untuk saya.Dan berikut ini postingan yang bagus tentang penggunaan enum dari Jake Wharton, lihatlah.
sumber
Tidak. " Strictly " artinya sangat buruk, tidak boleh digunakan sama sekali. Mungkin masalah kinerja mungkin muncul dalam situasi ekstrim seperti banyak banyak (ribuan atau jutaan) operasi dengan enum (berturut-turut pada utas ui). Jauh lebih umum adalah jaringan operasi I / O yang harus ketat terjadi di thread latar belakang. Penggunaan enum yang paling umum mungkin adalah semacam pemeriksaan tipe - apakah suatu objek adalah ini atau itu yang begitu cepat sehingga Anda tidak akan dapat melihat perbedaan antara satu perbandingan enum dan perbandingan bilangan bulat.
Tidak ada aturan umum untuk ini. Gunakan apa pun yang sesuai untuk Anda dan membantu Anda menyiapkan aplikasi. Optimalkan nanti - setelah Anda melihat ada hambatan yang memperlambat beberapa aspek aplikasi Anda.
sumber
Dengan Android P, google tidak memiliki batasan / keberatan dalam menggunakan enum
Dokumentasi telah berubah dimana sebelumnya disarankan untuk berhati-hati tetapi sekarang tidak disebutkan. https://developer.android.com/reference/java/lang/Enum
sumber
Dua fakta.
1, Enum adalah salah satu fitur paling kuat di JAVA.
2, ponsel Android biasanya memiliki BANYAK memori.
Jadi jawaban saya TIDAK. Saya akan menggunakan Enum di Android.
sumber
Saya ingin menambahkan, bahwa Anda tidak dapat menggunakan @Annotation saat mendeklarasikan List <> atau Map <> di mana salah satu kunci atau nilai adalah salah satu antarmuka anotasi Anda. Anda mendapatkan pesan kesalahan "Anotasi tidak diizinkan di sini".
enum Values { One, Two, Three } Map<String, Values> myMap; // This works // ... but ... public static final int ONE = 1; public static final int TWO = 2; public static final int THREE = 3; @Retention(RetentionPolicy.SOURCE) @IntDef({ONE, TWO, THREE}) public @interface Values {} Map<String, @Values Integer> myMap; // *** ERROR ***
Jadi ketika Anda perlu mengemasnya ke dalam daftar / peta, gunakan enum, karena mereka dapat ditambahkan, tetapi @annotated int / string groups tidak bisa.
sumber