#define в Java

Я начинаю программировать в Java, и я задаюсь вопросом если эквивалент C++ #define существует.

Быстрый поиск Google говорит, что не делает, но кто-либо мог сказать мне, если что-то подобное существует в Java? Я пытаюсь сделать свой код более читаемым.

Вместо myArray[0] Я хочу смочь записать myArray[PROTEINS] например.

68
задан Md. Abu Nafee Ibna Zahid 2 January 2018 в 15:16
поделиться

4 ответа

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

class MyClass
{
    private static final int PROTEINS = 0;

    ...

    MyArray[] foo = new MyArray[PROTEINS];

}

Компилятор заметит, что PROTEINS никогда, никогда не может измениться, и поэтому встроит его, что более или менее того, что вы хотите.

Обратите внимание, что модификатор доступа к константе здесь не важен, поэтому она может быть публичной или защищенной вместо частной, если вы хотите повторно использовать одну и ту же константу в нескольких классах.

92
ответ дан 24 November 2019 в 14:12
поделиться

Слишком мало места для комментариев, поэтому вот вам дополнительная информация об использовании static final . Как я сказал в своем комментарии к ответу Анджея , только примитив и String компилируются непосредственно в код как литералы. Чтобы продемонстрировать это, попробуйте следующее:

Вы можете увидеть это в действии, создав три класса (в отдельных файлах):

public class DisplayValue {
    private String value;

    public DisplayValue(String value) {
        this.value = value;
    }

    public String toString() {
        return value;
    }
}

public class Constants {
    public static final int INT_VALUE = 0;
    public static final DisplayValue VALUE = new DisplayValue("A");
}

public class Test {
    public static void main(String[] args) {
        System.out.println("Int   = " + Constants.INT_VALUE);
        System.out.println("Value = " + Constants.VALUE);
    }
}

Скомпилируйте их и запустите Test, который выведет:

Int    = 0
Value  = A

Теперь измените Константы , чтобы иметь разные значения для каждого и просто компилировать константы класса . Когда вы снова выполняете Test (без перекомпиляции файла класса), он по-прежнему печатает старое значение для INT_VALUE , но не VALUE . Например:

public class Constants {
    public static final int INT_VALUE = 2;
    public static final DisplayValue VALUE = new DisplayValue("X");
}

Запустить тест без перекомпиляции Test.java :

Int    = 0
Value  = X

Обратите внимание, что любой другой тип, используемый с static final , сохраняется в качестве ссылки.

Подобно C / C ++ #if / #endif , константный литерал или литерал, определенный с помощью static final с примитивами, используется в обычном условии Java if и имеет значение false заставит компилятор удалить байтовый код для операторов в блоке if (они не будут сгенерированы).

private static final boolean DEBUG = false;

if (DEBUG) {
    ...code here...
}

Код "... здесь код ..." не будет компилироваться в байтовый код. Но если вы измените DEBUG на true , то это будет.

константный литерал или литерал, определенный с помощью static final с примитивами, используется в обычном условии Java if и имеет значение false заставит компилятор удалить байтовый код для операторов в блоке if (они не будут сгенерированы).

private static final boolean DEBUG = false;

if (DEBUG) {
    ...code here...
}

Код "... здесь код ..." не будет компилироваться в байтовый код. Но если вы измените DEBUG на true , то это будет.

константный литерал или литерал, определенный с помощью static final с примитивами, используется в обычном условии Java if и имеет значение false заставит компилятор удалить байтовый код для операторов внутри блока if (они не будут сгенерированы).

private static final boolean DEBUG = false;

if (DEBUG) {
    ...code here...
}

Код в «... здесь код ...» не будет компилироваться в байтовый код. Но если вы измените DEBUG на true , то это будет.

не будет компилироваться в байтовый код. Но если вы измените DEBUG на true , то это будет.

не будет компилироваться в байтовый код. Но если вы измените DEBUG на true , то это будет.

38
ответ дан 24 November 2019 в 14:12
поделиться
static final int PROTEINS = 1
...
myArray[PROTEINS]

Обычно вы помещаете «константы» в сам класс. И обратите внимание, что компилятору разрешено оптимизировать ссылки на него, поэтому не меняйте его, если вы не перекомпилируете все используемые классы.

class Foo {
  public static final int SIZE = 5;

  public static int[] arr = new int[SIZE];
}
class Bar {
  int last = arr[Foo.SIZE - 1]; 
}

Цикл редактирования ... SIZE = 4 . Также скомпилируйте Bar , потому что ваш компилятор мог только что записать "4" в последнем цикле компиляции!

5
ответ дан 24 November 2019 в 14:12
поделиться

В Java нет директивы препроцессора общего назначения define .

В случае констант рекомендуется объявить их как static final , как в

private static final int PROTEINS = 100;

. Такие объявления будут встроены компиляторами (если значение является константой времени компиляции).

Обратите также внимание на то, что общедоступные статические конечные константные поля являются частью открытого интерфейса, и их значения не должны изменяться (поскольку компилятор встраивает их). Если вы все же измените значение, вам придется перекомпилировать все источники, ссылающиеся на это поле константы.

4
ответ дан 24 November 2019 в 14:12
поделиться
Другие вопросы по тегам:

Похожие вопросы: