Android'de Enums ile çalışma


120

Uygulamam için android üzerinde çalıştığım bir hesaplama etkinliğini neredeyse bitirdim. Bir Cinsiyet Enumu oluşturmaya çalışıyorum, ancak nedense Sözdizimi hatası alıyorum, EnumDeclaration'ı tamamlamak için "EnumBody" ekleyin.

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

Ayrıca {} statik olmadan da denedim ama aynı sözdizimi hatası alıyorum.


Numaralandırmalar performans sorunları için önerilmez, bunun yerine temel sabitleri kullanın. youtube.com/watch?v=Hzs6OBcvNQE
Myke Dev

GÜNCELLEME 2019: ART, DALVIK'i çalışma zamanı ortamı stackoverflow.com/a/56296746/4213436 olarak değiştirdiğinden, numaralandırmaların Android'de kullanılması uygundur . Bu nedenle, bu konudaki çoğu yanıtın alakasız olduğunu düşünüyorum.
JDenais

@JDenais elbette az önce referans verilen 'siz'
dizisini kastediyorsunuz

Yanıtlar:


343

Bu sözdizimini dünyanın neresinde buldunuz? Java Numaralandırmaları çok basittir, siz sadece değerleri belirlersiniz.

public enum Gender {
   MALE,
   FEMALE
}

Daha karmaşık olmalarını istiyorsanız onlara bu şekilde değerler ekleyebilirsiniz.

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

Ardından sıralamayı kullanmak için şöyle bir şey yaparsınız:

Gender me = Gender.MALE

12
Bunu bir deneyeceğim, mutlak bir acemi
olduğumu söyledim

87
Üzgünüm, bunu olumsuz olarak kastetmedim. Bir Enum için şimdiye kadar gördüğüm en tuhaf sözdizimi
Spidy

4
Ayrıca numaralandırmaların sıralı olduğundan bahsetmek de yararlıdır, böylece int değerini elde etmek için numaralandırmada .ordinal () kullanabilirsiniz.
Kalel Wade

1
Sorudaki sözdizimi, bir derleyici kullanarak ortaya çıkabilecek türden bir sözdizimi.
Dan Getz

9
"Bu söz dizimini nerede buldunuz" üzerine çok güldüm. Öğrencisine tıpkı bir öğretmen gibi söylüyor
Zar E Ahmer

50

Bu çekişme noktası etrafında bazı tartışmalar oldu, ancak en son belgelerde bile android, bir android uygulamasında numaralandırma kullanmanın o kadar iyi bir fikir olmadığını öne sürüyor. Bunun nedeni, statik sabitler değişkeninden daha fazla bellek kullanmalarıdır. Bir android uygulamasında numaralandırma kullanımına karşı tavsiyelerde bulunan 2014 sayfasından bir belge. http://developer.android.com/training/articles/memory.html#Overhead

Alıntı yaparım:

Bellek yükünün farkında olun

Kullandığınız dil ve kitaplıkların maliyeti ve ek yükü hakkında bilgi sahibi olun ve uygulamanızı tasarlarken baştan sona bu bilgileri aklınızda bulundurun. Çoğu zaman, yüzeydeki zararsız görünen şeyler aslında büyük miktarda ek yüke sahip olabilir. Örnekler şunları içerir:

  • Numaralandırmalar genellikle statik sabitlerin iki katından daha fazla bellek gerektirir. Android'de numaralandırmaktan kesinlikle kaçınmalısınız.

  • Java'daki her sınıf (anonim iç sınıflar dahil) yaklaşık 500 bayt kod kullanır.

  • Her sınıf örneğinin 12-16 bayt RAM ek yükü vardır.

  • Bir HashMap'e tek bir giriş koymak, 32 bayt alan ek bir giriş nesnesinin tahsis edilmesini gerektirir (optimize edilmiş veri konteynerleri hakkında önceki bölüme bakın).

Burada ve orada birkaç bayt hızla toplanır - sınıf veya nesne ağırlıklı uygulama tasarımları bu ek yükten zarar görür. Bu sizi bir yığın analizine bakmanın ve probleminizin RAM'inizi kullanan çok sayıda küçük nesnenin farkına varmanın zor konumunda bırakabilir.

Bu ipuçlarının modası geçmiş ve artık değerli olmadığını söyledikleri bazı yerler oldu, ancak bunu tekrar etmeye devam etmelerinin nedeni, bazı gerçekler olmalı. Bir android uygulaması yazmak, sorunsuz bir kullanıcı deneyimi için olabildiğince hafif tutmanız gereken bir şeydir. Ve her küçük inç performans önemlidir!


Bazı yerler oldu - biliyorsan ekleyebilir misin? çünkü bulamıyorum
Krzysztof Skrzynecki

9
Burada biri, numaralandırma yerine girişleri kullanma hakkındaki bilgilerin resmi belgelerde Performans İpuçları'ndan kaldırıldığını fark etti . Dahası, reddit hakkında
Krzysztof Skrzynecki


Arkadaşlar, sorum şu: Enum "kötü" bir uygulama ise, Google neden Java'nın bu özelliğini Android ile hala destekliyor? :(
Jesús Castro

5
@ JesúsCastro Çünkü Google, çok sayıda mevcut Java iş mantığına sahip şirketlerin (numaralandırma kullanıyor olabilir) kitaplıklarını bir Android projesine bırakıp gidebilmesini sağlamak istiyor.
David Brown

22

Chris'in yorumladığı gibi, numaralandırmalar, Android'de her yerde kullanılmaya devam ettikçe toplanan çok daha fazla bellek gerektirir. Bunun yerine, derleyicinin geçirilen değerleri doğrulaması için ek açıklamalar kullanan IntDef veya StringDef'i denemelisiniz .

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

İkili bileşime (VEYA / VE işlemleri) izin veren bayraklar olarak da kullanılabilir.

DÜZENLEME : Numaralandırmaları girişlere dönüştürmek, Proguard'daki varsayılan optimizasyonlardan biri gibi görünüyor .


3
İnt sabitlerini doğrudan açıklama sınıfına yerleştirmeyi seviyorum. Böylece normal numaralandırma gibi görünür. Bunu burada anlattım
Oleksii K.


9

Bu Videoya göre , ProGuard kullanıyorsanız Enums performans sorunlarını düşünmenize bile gerek yok !!

Proguard, birçok durumda Enums'i INT değerlerine optimize edebilir, böylece gerçekten bunun hakkında düşünmenize veya herhangi bir iş yapmanıza gerek kalmaz.


4

Android'in tercih edilen yaklaşımı, @IntDef ile zorunlu kılınan int sabitleridir:

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

Dokümanlar: https://developer.android.com/studio/write/annotations.html#enum-annotations

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.