Когда использовать Enum/Int Constants

У меня вопрос, когда следует использовать Enum и когда мы должны использовать конечные константы?

Я знаю, что это обсуждалось в Enums и Constants. Что использовать, когда? хотя это вопрос С#.

Мой вопрос: почему Android использует так много констант, а не Enum? Например, Context

На мой взгляд, если мы используем константы, может быть риск, что ниже: если мы определим константу LEVEL, что

 public static final int LEVEL_LOW=1;
 public static final int LEVEL_MEDIUM=2;
 public static final int LEVEL_HIGH=3;

когда мы передаем параметр int = 4. он не будет компилировать ошибку, и если мы пройдем число 1, читатель кода может не легко узнать, что это значит.

Но Enum может решить эту проблему, хотя это может вызвать дополнительные накладные расходы, поскольку это Object.

Итак, почему Android использует константы вместо Enum? Есть ли какой-либо принцип, что когда мы должны использовать константы или Enum в таком случае?

Ответ 1

Это связано с историей Android. В версиях до Froyo были неподтвержденные проблемы с производительностью. Было рекомендовано не использовать enum разработчиками. Поскольку документация Froyo Designing for Performance была переписана, как описано здесь.

Как вы, возможно, заметили, мы переписали Designing for Performance документация для Froyo. Раньше это была куча вещей, которые могут в какой-то момент были верны, но уже давно отношения к реальности. В Froyo каждая претензия в документе подкрепляется эталоном, чтобы доказать (или, в будущем, опровергнуть) его. Вы могут просмотреть тесты "Разработка для производительности" в вашем браузере.

Но не было смысла изменять структуру устаревшего контента.

Производительность может быть связана с тем, что требуется сохранить String. Существует значительная разница между созданием одного класса для каждой константы или множественных перечислений.

Например, в Java 7, когда у вас есть перечисление с двумя полями, вам нужно 44 элемента в константе опроса, а для класса с двумя статическими конечными целыми числами вам нужно всего 17.

В чем разница

class ContantField {
  public static final int f1 = 0;
  public static final int f2 = 1;
}

enum ContantEnum {
  E1,E2
}

Эти два объявления сильно отличаются в том, как они хранятся и используются. Упрощение ContantEnum может выглядеть как

class ContantEnum {
   public static final Enum enum0    = new Enum("V1",0);
   public static final Enum enum1    = new Enum("V2",1);
   public static final Enum[] values = new Enum[] {enum0,enum1};
} 

Благодаря этому упрощению можно заметить, что enum требует больше ресурсов памяти, чем int.

Чтобы ответить на ваш вопрос, нужно понимать роль перечислений. Одна из функций перечисления заключается в повышении безопасности типа времени компиляции.

Чтобы указать на этот пример:

public void setImportantThing(int priviledge, int rights)

public void setImportantThing(Privilege p, Right r)

В случае int мы можем передать любое значение, которое является int. В этом случае enum мы вынуждены использовать правильный.

Здесь мы имеем дело с компромиссом между проверкой времени компиляции и использованием памяти во время выполнения. Вы должны решить для себя, когда вы должны использовать enum и где static int достаточно безопасно.

Примечание:  enum был представлен Java в версии 1.5, используя их до того, как это было довольно проблематично больше.

В Android Studio Beta разработчик сможет обеспечить безопасность типов с помощью аннотации.

Ответ 2

Перечисления:

  • Более безопасный - более устойчивый к изменению.

    Изменение списка перечислений, скорее всего, вызовет ошибки времени компиляции, если изменение было ошибочным.

  • Clearer - большинство разработчиков сразу поймут, что элементы связаны каким-то образом.

    enum { A, B, C } гораздо более очевидно группа элементов с соединением, чем psfi A = 0; psfi B = 1; psfi C = 2;

Итак, если у вас нет измеримого преимущества использования public static final int, будь то в области памяти или скорости памяти, вы всегда должны использовать enum.

См. Когда оптимизация преждевременна?

Ответ 3

В основном ядро ​​Android - это код C/С++. Это работает с целыми числами. Поэтому при использовании перечислений в Java каждое значение должно быть "переведено". Это будет стоить процессорное время и память. Оба они встречаются редко на встроенных системах.

Ответ 4

Проще говоря, Enums использует больше ресурсов, чем общедоступные статические конечные поля, поэтому не используйте ENUM в мобильной программировании, где подсчитывается каждый байт.

http://developer.android.com/training/articles/perf-tips.html#UseFinal

Ответ 5

Когда я программирую лично, я использую ваш метод выше, когда хочу, чтобы имя представляло собой важное целое число. Например, MAX_INT, который может сопоставляться с int 50. Это полезно, потому что я могу изменить int на 60, если захочу, не пройдя весь свой код и не изменив 50-х до 60-х.

С перечислением это (как эта ссылка) специальный тип данных, который позволяет переменной быть набором предопределенных констант, Таким образом, это был бы идеальный выбор, если бы вы хотели иметь ограниченный набор значений для выбора - тогда как выбранный вами стиль выше был бы расширяемым и, как сказано, легко использовать, выбирая значение не в границах.