#define в Java

Я начинаю программировать на Java, и мне интересно, эквивалентен ли c++ .

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

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

7 ответов


нет, потому что нет прекомпилятором.

тем не менее, Hotspot довольно удивительно хорош в оптимизации, где это возможно, поэтому в вашем случае вы можете достичь того же самого:

class MyClass
{
    private static final int PROTEINS = 0;

    ...

    MyArray[] foo = new MyArray[PROTEINS];

}

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

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


пространство комментариев слишком мало, поэтому вот еще одна информация для вас об использовании 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);
    }
}

скомпилируйте их и запустите тест, который печатает:

Int    = 0
Value  = A

теперь измените Constants чтобы иметь разное значение для каждого и просто скомпилировать class Constants. При выполнении 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 block (они не будут сгенерированы).

private static final boolean DEBUG = false;

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

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


static final int PROTEINS = 1
...
myArray[PROTEINS]

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

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 " в последнем цикле компиляции!


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

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

private static final int PROTEINS = 100;

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

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


здесь препроцессор для Java который предоставляет директивы, такие как #define, #ifdef, #ifndef и многие другие, например, команда PostgresJDBC использует его для создания источников для разных случаев и не дублировать код.


самый простой ответ "нет прямого метода его получения, потому что нет предварительного компилятора" Но вы можете сделать это сами. Используйте классы, а затем определите переменные как финал так что можно считать постоянным на протяжении всей программы
Не забудьте использовать final и variable как public или protected not private, иначе вы не сможете получить к нему доступ извне этого класса


большинство читабельный решение заключается в использовании Статический Импорт. Тогда вы будете не нужно использовать AnotherClass.constant.

напишите класс с константой as public static поле.

package ConstantPackage;

public class Constant {
    public static int PROTEINS = 1;
}

тогда просто используйте Статический Импорт где вам нужна константа.

import static ConstantPackage.Constant.PROTEINS;

public class StaticImportDemo {

    public static void main(String[]args) {

        int[] myArray = new int[5];
        myArray[PROTEINS] = 0;

    }
}

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