Чому Android не використовує більше перерахувань?


79

Я почав дуже любити використовувати перерахування C # та Java у своєму коді з кількох причин:

  • Вони набагато безпечніші для типу, ніж цілі числа, рядки або набори логічних прапорів.
  • Вони ведуть до більш читабельного коду.
  • Набагато важче встановити для переліку недійсне значення, ніж int або рядок.
  • Вони полегшують виявлення допустимих значень для змінної чи параметра.
  • Все, що я прочитав, свідчить про те, що вони працюють так само добре, як цілі числа в C # та більшості JVM.

Однак у фреймворку Android є численні випадки, коли потрібно передавати прапори різних типів, але, схоже, жоден з них не використовує перелічення. Кілька прикладів , коли я думаю , що їх використання було б корисно в Toast.LENGTH_SHORT/ Toast.LENGTH_LONGі View.GONE, View.VISIBLEі т.д.

Чому це? Чи ефективні перерахування в Dalvik, ніж прості цілі числа? Чи є якийсь інший недолік, про який я не знаю?


10
Нормально використовувати enum зараз. Дивіться stackoverflow.com/questions/5143256/…
Тьєррі-Дімітрі Рой

1
Чудово! Мені подобаються переліки, і я їх ще не дістав.
Ми всі Моніка

Відповіді:


66

Ця відповідь застаріла станом на березень 2011 року.

Enums можна використовувати на Froyo та новіших версіях - відповідно до цієї відповіді ( Чому було видалено «Уникати перелічень там, де потрібні лише інти» з підказок щодо ефективності Android? ) Від члена команди Android VM (та його блогу ).


Попередня відповідь:

Офіційна рекомендація команди Android полягає в тому, щоб уникати перелічень, коли ви можете цього уникнути:

Перерахування дуже зручні, але, на жаль, можуть бути болючими, коли розмір і швидкість мають значення. Наприклад, це:

public enum Shrubbery { GROUND, CRAWLING, HANGING }

додає 740 байт до вашого файлу .dex порівняно з еквівалентним класом із трьома загальнодоступними статичними кінцевими входами. При першому використанні ініціалізатор класу викликає метод для об’єктів, що представляють кожне з перерахованих значень. Кожен об'єкт отримує своє власне статичне поле, а повний набір зберігається в масиві (статичне поле під назвою "$ VALUES"). Це багато коду та даних, лише для трьох цілих чисел. Крім того, це:

Shrubbery shrub = Shrubbery.GROUND;

викликає пошук статичного поля. Якби "GROUND" був статичним кінцевим int, компілятор розглядав би його як відому константу та вбудовував.

Джерело: Уникайте переліків, де вам потрібні лише інти


4
Таким чином , в той час як C # перерахувань дійсно виконують дуже добре, Java перерахувань не так як вони є більш складними. Тому мій останній пункт не відповідає дійсності. Правильно?
Ми всі Моніка

25
Це, мабуть, вже не дійсне, див. Stackoverflow.com/questions/5143256/…
Віктор Даль

2
Документація Android все ще радить не використовувати перелічення : "Перечислення часто вимагають більше, ніж удвічі більше пам'яті, ніж статичних констант. Вам слід суворо уникати використання перерахувань на Android". developer.android.com/training/articles/memory.html#Overhead
ThomasW

1
@ SebastianPaaskeTørholm Посилання, яке ви надали (це: developer.android.com/guide/practices/design/… ), більше не відображає підказки.
розробник android

14

Цілі числа менші та потребують менших накладних витрат, що все одно має значення на мобільних пристроях.


Крім того, тепер у нас є хороший інструмент для Android Studio та Lint. Я маю на увазі анотації IntDefта StringDef, які дозволяють оголосити якийсь typedef , тому використання констант int дуже зручно. blog.shamanland.com/2016/02/int-string-enum.html
Олексій К.

так, але як щодо моделей модернізації? (і для інших мережевих бібліотек, я припускаю) Як би ви визначили відповідь статусу (наприклад, вдалося, не вдалося, термін дії_тече) закінчився безпосередньо на POJO?
mitsest

5

Мій колега провів невеликий тест щодо цієї ситуації. Він автоматично згенерував a classта an enumіз такою ж кількістю "переліків". Я вважаю, що він створив 30000 записів.

Результати:

  • .classдля classприблизно 1200 Кб
  • .classдля цього enumбуло приблизно 800 КБ

Сподіваюся, це комусь допомагає.


Я не думаю, що це дійсний тест. Наявність 30000 переліків / статичних полів в одному місці не є реалістичним сценарієм. Вам потрібно буде порівняти розмір великої кількості малих класів / переліків, наприклад 1000 класів / переліків по 30 властивостей кожен. Б'юсь об заклад, що загальний розмір буде зовсім іншим.
Iwo Banas,

7
@Iwo Banas Будь-який тест є дійсним тестом. Не сказав, що відповість на питання. Просто запропонував це як додаткову інформацію для всіх, кого це може зацікавити. І голосування проти здається дуже заслуженим, тож спасибі. -_-
prolink007

Хіба це не свідчить про протилежне? Що enum використовує менше? І це пам’ять чи пам’ять 1200 КБ або 800 КБ?
розробник android
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.