#define в Java
Я начинаю программировать на Java, и мне интересно, существует ли эквивалент C++ #define
.
Быстрый поиск в Google говорит, что это не так, но может кто-нибудь сказать мне, если что-то подобное существует в Java? Я пытаюсь сделать мой код более читабельным.
Вместо myArray[0]
я хочу иметь возможность написать myArray[PROTEINS]
например.
Ответы
Ответ 1
Нет, потому что нет прекомпилятора. Тем не менее, в вашем случае вы можете достичь того же, что и ниже:
class MyClass
{
private static final int PROTEINS = 0;
...
MyArray[] foo = new MyArray[PROTEINS];
}
Компилятор заметит, что PROTEINS
никогда, никогда не изменится, и поэтому встроит его, что более или менее то, что вы хотите.
Обратите внимание, что модификатор доступа к константе здесь не важен, поэтому он может быть public
или protected
а не закрытым, если вы хотите повторно использовать одну и ту же константу в нескольких классах.
Ответ 2
Слишком мало места для комментариев, так что вот вам еще немного информации об использовании static final
. Как я сказал в своем комментарии к ответу Andrzej, только примитив и 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
Теперь измените Constants
чтобы они имели разные значения для каждого, и просто скомпилируйте класс 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
блок (они не будут сгенерированы).
private static final boolean DEBUG = false;
if (DEBUG) {
...code here...
}
Код в "... код здесь..." не будет скомпилирован в байт-код. Но если бы вы изменили DEBUG
на true
тогда это было бы так.
Ответ 3
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" в последнем цикле компиляции!
Ответ 4
Java не имеет директивы препроцессора общего назначения define
.
В случае констант рекомендуется объявить их как static finals
, как в
private static final int PROTEINS = 100;
Такие объявления были бы заключены компиляторами (если значение является константой времени компиляции).
Обратите внимание, что общедоступные статические конечные константные поля являются частью открытого интерфейса, и их значения не должны меняться (поскольку компилятор строит их). Если вы измените значение, вам нужно будет перекомпилировать все источники, которые ссылаются на это постоянное поле.
Ответ 5
Существует препроцессор для Java, который предоставляет директивы, такие как #define, #ifdef, #ifndef и многие другие, например, команда PostgresJDBC использует его для генерации исходников для различных случаев и не для дублирования кода.
Ответ 6
Самый простой ответ: "Нет прямого метода получения, потому что нет предварительного компилятора"
Но вы можете сделать это сами. Используйте классы, а затем определите переменные как final, чтобы их можно было считать постоянными во всей программе
Не забудьте использовать конечные и переменные как общедоступные или защищенные, а не частные, иначе вы не сможете получить доступ к нему из-за пределов этого класса
Ответ 7
Наиболее читаемым решением является использование статического импорта. Тогда вам не нужно будет использовать AnotherClass.constant
.
Напишите класс с константой в качестве public static
поля.
package ConstantPackage;
public class Constant {
public static int PROTEINS = 1;
}
Тогда просто используйте Static Import там, где вам нужна константа.
import static ConstantPackage.Constant.PROTEINS;
public class StaticImportDemo {
public static void main(String[]args) {
int[] myArray = new int[5];
myArray[PROTEINS] = 0;
}
}
Чтобы узнать больше о статическом импорте, посмотрите этот вопрос о переполнении стека.
Ответ 8
Java Primitive Specializations Generator поддерживает /* with */
, /* define */
и /* if */.../* elif */.../* endif */
блоками, которые позволяют создавать макросы в Java код, похожий на java-comment-препроцессор, упомянутый в этом ответе.
JPSG имеет плагины Maven и Gradle.