Робота з Enums в андроїді


120

Я майже закінчуюсь з розрахунковою діяльністю, з якою працюю в 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;
    }
}

Я також спробував це без статичної {}, але я отримую ту саму синтаксичну помилку.


Енуми не рекомендуються для проблем з продуктивністю, замість цього використовуйте примітивні константи. youtube.com/watch?v=Hzs6OBcvNQE
Myke Dev

ОНОВЛЕННЯ 2019: Енуми чудово використовувати в Android, оскільки ART замінив DALVIK як середовище виконання stackoverflow.com/a/56296746/4213436 . Тому я вважаю, що більшість відповідей на цю тему не мають значення.
JDenais

@JDenais, звичайно, ви маєте на увазі тему "ви", яку ви просто
посилалися

Відповіді:


343

Де ви знайшли цей синтаксис? Java Enums дуже прості, ви просто вказуєте значення.

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

12
Спробую, я сказала, що я абсолютно новачок
JMSDEV

87
Вибачте, я це не мав на увазі негативно. Просто найдивніший синтаксис, який я коли-небудь бачив для Enum
Spidy

4
Також корисно згадати, що перелічення є послідовними, тому ви можете використовувати .ordinal () на enum, щоб отримати значення int.
Калель Вейд

1
Синтаксис у питанні такий, який можна було б створити з використанням декомпілятора.
Dan Getz

9
Я так сміявся над "Де на землі ти знайшов цей синтаксис". Сказав так само, як вчитель своєму учневі
Зар Е Ахмер

50

Існували певні суперечки з цього приводу суперечок, але навіть в останніх документах андроїд припускає, що використовувати переписки в додатку для android не так добре. Причина тому, що вони використовують більше пам'яті, ніж статична константа. Ось документ зі сторінки 2014 року, який не радить використовувати переписки в додатку для android. http://developer.android.com/training/articles/memory.html#Overhead

Цитую:

Будьте в курсі пам’яті накладні

Будьте обізнані про вартість і накладні витрати мови та бібліотек, якими ви користуєтесь, і пам’ятайте про цю інформацію, коли ви розробляєте додаток, від початку до кінця. Часто речі на поверхні, які виглядають нешкідливими, насправді можуть мати велику кількість накладних витрат. Приклади включають:

  • Енумам часто потрібно більше ніж удвічі більше пам’яті, ніж статичні константи. Вам слід суворо уникати використання переписок на Android.

  • Кожен клас на Java (включаючи анонімні внутрішні класи) використовує близько 500 байт коду.

  • Кожен екземпляр класу має 12-16 байт оперативної пам’яті.

  • Введення одного запису в HashMap вимагає виділення додаткового об'єкта введення, який займає 32 байти (див. Попередній розділ про оптимізовані контейнери даних).

Кілька байтів тут і там швидко додаються - дизайн додатків, які важкі для класу чи об'єкта, постраждає від цього накладних витрат. Це може поставити вас у скрутне становище при аналізі купи і усвідомленні вашої проблеми - це багато дрібних об'єктів, які використовують вашу оперативну пам’ять.

Там були місця, де вони говорять про те, що ці поради застаріли і вже не є цінними, але причина, по якій вони повторюють це, повинна бути в чомусь правда. Написання програми для андроїд - це те, що вам слід зберігати якомога легше для безперебійного користування. І кожен маленький дюйм продуктивності рахується!


Там були місця - ви могли б додати їх, якщо знаєте їх? тому що я не можу знайти жодного
Krzysztof Skrzynecki

9
Тут хтось помітив, що інформація про використання ints замість enums була видалена з Поради щодо ефективності в офіційній документації. Більше того, я зробив дослідження та розмістив резюме на reddit
Krzysztof Skrzynecki

1
Моделі продуктивності Android: ціна ENUM (100 днів Google Dev)
Afriza N. Arief

Хлопці, моє питання, якщо Enum "погана" практика, чому Google все ще підтримує цю функцію Java з Android? :(
Jesús Castro

5
@ JesúsCastro Оскільки Google хоче забезпечити, щоб компанії з великою кількістю існуючих бізнес-логік Java (які, можливо, використовують переписки) могли просто перенести свою бібліотеку в проект Android і перейти.
Девід Браун

22

Як зауважив Кріс, перелікам потрібно набагато більше пам’яті на Андроїд, який збільшується, оскільки вони постійно використовуються скрізь. Ви повинні спробувати 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);

Він також може бути використаний як прапорці, що забезпечує бінарний склад (АБО / ІН).

EDIT : Здається, що перетворення enums в ints є однією з оптимізацій за замовчуванням у Proguard .


3
Мені подобається розміщувати константи Int безпосередньо в класі анотацій. Таким чином, це виглядає як звичайний перерахунок. Я описав це тут: blog.shamanland.com/2016/02/int-string-enum.html
Олексій К.


9

Відповідно до цього відео, якщо ви користуєтеся програмою ProGuard, вам навіть не потрібно думати про проблеми продуктивності Enums !!

Proguard може у багатьох ситуаціях оптимізувати значення Enums до INT від вашого імені, тому дійсно не потрібно думати про це чи робити якусь роботу.


4

Кращим підходом Android є int-константи, що застосовуються за допомогою @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;
  }
}

Документи: https://developer.android.com/studio/write/annotations.html#enum-annotations

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.