Почему Android не использует больше перечислений?
Мне очень понравилось использовать С# и Java перечисления в моем коде по нескольким причинам:
- Они гораздо более безопасны по типу, чем целые числа, строки или наборы логических флагов.
- Они приводят к более читаемому коду.
- Сложнее установить перечисление на недопустимое значение, чем int или string.
- Они позволяют легко обнаружить допустимые значения для переменной или параметра.
- Все, что я прочитал, указывает, что они выполняют так же, как и целые числа в С# и большинстве JVM.
Однако в платформе Android есть множество случаев, когда флаги разных типов должны быть переданы, но ни один из них, похоже, не использует перечисления. Несколько примеров, в которых я думаю, что их использование будет полезным, - это Toast.LENGTH_SHORT
/Toast.LENGTH_LONG
и View.GONE
, View.VISIBLE
и т.д.
Почему это? Делают ли перечисления хуже, чем простые целочисленные значения в Dalvik? Есть ли еще какой-то недостаток, о котором я не знаю?
Ответы
Ответ 1
Этот ответ устарел с марта 2011 года.
Перечисления могут использоваться на Froyo и выше - в соответствии с этим ответом (Почему "Избегайте перечислений, где вам нужны только инты" , удалены из рекомендаций по производительности Android?) из член команды Android VM (и его блог).
Предыдущий ответ:
Официальная рекомендация команды Android состоит в том, чтобы избежать перечислений, когда вы можете избежать этого:
Перечисления очень удобны, но к сожалению, может быть больно, когда размер и скорость вещества. Например, это:
public enum Shrubbery { GROUND, CRAWLING, HANGING }
добавляет 740 байт к ваш файл .dex по сравнению с эквивалентный класс с тремя общедоступными статические окончательные ints. При первом использовании инициализатор класса вызывает метод на объектах, представляющих каждый из перечисленные значения. Каждый объект получает свое собственное статическое поле, а полный набор хранится в массиве (a статическое поле под названием "$ VALUES" ). Это много кода и данных, всего за три целые числа. Кроме того, это:
Shrubbery shrub = Shrubbery.GROUND;
вызывает поиск статического поля. Если "GROUND" были статическим окончательным int, компилятор будет рассматривать его как известный постоянный и встроенный.
Источник: Избегайте перечислений, где вам нужны только инты
Ответ 2
Целые числа меньше и требуют меньших накладных расходов, что еще важно для мобильных устройств.
Ответ 3
Мой коллега выполнил небольшое испытание относительно этой ситуации. Он автоматически сгенерировал
class
и enum
с таким же количеством "перечислений". Я считаю, что он создал 30000 записей.
Результаты:
-
.class
для class
составлял примерно 1200 КБ
-
.class
для enum
было примерно 800 КБ
Надеюсь, это поможет кому-то.