Морбидное использование констант

Почему я должен писать (как говорит мой коллега):

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 отвечая с точки зрения преимуществ использования магических чисел, я никоим образом (я думал, что это было неописуемо, приходите на людей), советуя изменить константу библиотеки.