Морбидное использование констант
Почему я должен писать (как говорит мой коллега):
import static org.apache.commons.lang.math.NumberUtils.INTEGER_ONE;
if (myIntVariable == INTEGER_ONE) { ... }
вместо:
if (myIntVariable == 1) { ... }
?
Я знаю, что рекомендуется использовать константы, но я думаю, что значение NumberUtils.INTEGER_ONE
никогда не изменится! Поэтому я пишу 1
.
Ответы
Ответ 1
Вы не должны. Имя INTEGER_ONE
больше не имеет смысла, чем 1. Если это значение имеет какое-то другое значение (например, месяц в году), то использование константы (например, Calendar.FEBRUARY
) сделает ваш код более четким.
Я могу предположить, что эта константа в библиотеке Commons Math была создана в Java 1.4, когда не было кеша Integer и автобоксинга, поэтому он имел смысл в терминах, что вы можете повторно использовать один и тот же объект Integer
(не примитивный int
) в разных местах для сохранения памяти. Поэтому он был добавлен по соображениям производительности, а не для ясности кода. Теперь он устарел: даже если вам нужен объект Integer
, вы можете использовать Integer.valueOf(1)
или неявное автобоксирование и получить кешированный файл.
Ответ 2
Вы не должны писать INTEGER_ONE
! Также вы не должны писать 1
(см. Исключение ниже)!
Почему? Литерал, подобный 1
, называется магическим числом . Магические числа - это "уникальные значения с необъяснимым значением или множественные случаи, которые могут (желательно) быть заменены именованными константами" (пояснение с той же страницы Википедии).
Итак, что обычно должно быть сделано, это превращение этих магических чисел в константы, чье имя представляет или объясняет значение этого числа. Константа INTEGER_ONE
не объясняет смысла.
Итак, вам действительно нужно найти значение значения в этом контексте и создать константу с таким именем. Если 1
представляет максимальное количество разрешенных потоков, например, у вас должна быть константа, например:
static final int MAX_NUMBER_OF_THREADS = 1;
ИЗМЕНИТЬ в соответствии с комментарием Tagir
Если сам литерал имеет значение в домене, для которого вы пишете код, тогда он не должен заменяться именованной константой. Пример Тагира для вычисления обратного элемента является хорошим:
double invert(double x) {
return 1/x;
}
Здесь литерал 1
имеет смысл в этом контексте внутри области математики. Поэтому его можно использовать как есть.
Ответ 3
У меня есть только что написанные стили для моей компании, и я бы предложил следующее:
Не используйте жестко закодированные "магические" значения. Если значение является постоянным, определите его как таковое. В некоторых ситуациях могут использоваться такие числа, как -1, 0, 1, 2, 100.
Мои примеры находятся в Objective-C как язык, на котором я писал рекомендации, но правила все еще применяются.
Хорошее использование
static NSString* const DatabaseName = @"database.name";
//Acceptable use of "2"
float x = (ScreenWidth / 2) - (ImageWidth / 2);
//Acceptable use of 0
for (int i = 0; i < NumberOfItems; i++)
//Acceptable use of 100, but only because the variable is called "percentage"
float percentage = (someObjects * 100) / allObjects.count;
Плохое использование
float x = (480 / 2) - (120 / 2); //We have to guess these are sizes?
//Unneccessary constants.
for (int i = ZERO; i < NumberOfItems; i += ONE)
float percentage = (someObjects.count * 100) / 120; //What is 120?
Ответ 4
org.apache.commons.lang.math.NumberUtils.INTEGER_ONE
он дает вам объект final static Integer
, а не примитивный int
1, а поскольку он final static
, он действует как константа и может использоваться для сравнения объектов Integer
, потому что всегда будет возвращать одинаковые экземпляр.
Итак, в приведенном выше сценарии это может выглядеть не так, но где-то, если вы используете его во время сравнения, это наверняка повлияет.
Кроме того, насколько мы можем, следует предпочесть использование констант по сравнению с жестко закодированным beacuse:
- Он может сделать ваш код легко поддерживаемым. Если в будущем ситуация изменится, вы можете изменить ее только в одном месте.
- Код выглядит более понятным и понятным.
Ответ 5
Вы можете узнать, не изменится ли он, но я не буду, если я начну редактировать свой код...
В основном это способ документирования вашего кода в вашем фактическом коде. Причина использования констант и подобных примеров заключается в том, чтобы избежать Магических чисел в коде и их недостатках.
Говоря это, вы можете использовать его до такой степени, когда это не выгодно и не создает помех. Я имею тенденцию делать это для вещей, которые используются более одного раза или имеют концепцию изменения мной или кем-то еще... или в более простых выражениях важные значения.
Ответ 6
Из Class NumberUtils вы увидите, что он определен как:
/** Reusable Integer constant for one. */
public static final Integer INTEGER_ONE = new Integer(1)
Итак, вы увидите, что INTEGER_ONE не совпадает с 1. Это объект, который уже был создан для вас. Итак, если нам нужен экземпляр Integer(1)
, а не создать свой собственный, вы можете повторно использовать его из библиотеки, экономя время и память.
Это действительно зависит от вашего приложения, если вы действительно используете int
версию 1, то, вероятно, вам лучше использовать это вместо этого класса Integer
.
Ответ 7
Представьте, что у вас есть этот
if (myIntVariable == 1) { ... }
Но несколько тысяч раз...
И вдруг нужно быть 2.
Что вам легче изменить?
РЕДАКТИРОВАТЬ: Перед тем, как свалить, im отвечая с точки зрения преимуществ использования магических чисел, я никоим образом (я думал, что это было неописуемо, приходите на людей), советуя изменить константу библиотеки.