我开始用Java编程,我想知道是否存在与C ++ #define
相当的东西。
快速搜索谷歌说它没有,但任何人都可以告诉我是否存在类似的东西 在Java? 我正在尝试让我的代码更具可读性。
而不是myArray[0]
我希望能够编写myArray[PROTEINS]
例如。
答案 0 :(得分:88)
不,因为没有预编译器。但是,在您的情况下,您可以实现以下相同的目的:
class MyClass
{
private static final int PROTEINS = 0;
...
MyArray[] foo = new MyArray[PROTEINS];
}
编译器会注意到PROTEINS
永远不会改变,所以会内联它,这或多或少都是你想要的。
请注意,常量上的访问修饰符在这里并不重要,因此如果您想在多个类中重复使用相同的常量,那么它可以是public
或protected
而不是私有。
答案 1 :(得分:37)
评论空间太小,所以这里有关于static final
使用的更多信息。正如我在Andrzej's answer的评论中所说,只有原语和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
条件并计算为{ {1}}将导致编译器剥离false
块中语句的字节代码(不会生成它们)。
if
“...... code here ...”中的代码不会被编译成字节代码。但是,如果您将private static final boolean DEBUG = false;
if (DEBUG) {
...code here...
}
更改为DEBUG
,那么就是。
答案 2 :(得分:5)
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”!
答案 3 :(得分:4)
Java没有通用的define
预处理程序指令。
对于常量,建议将它们声明为static finals
,就像在
private static final int PROTEINS = 100;
这些声明将由编译器内联(如果值是编译时常量)。
另请注意,public static final常量字段是公共接口的一部分,它们的值不应更改(因为编译器会内联它们)。如果确实更改了值,则需要重新编译引用该常量字段的所有源。
答案 4 :(得分:3)
有preprocessor for Java提供#define,#ifdef,#ifndef等指令,例如PostgresJDBC团队使用它来为不同的情况生成源并且不重复代码。
答案 5 :(得分:0)
最简单的答案是"没有直接获取方法,因为没有预编译器"
但你可以自己做。使用类然后将变量定义为 final ,以便在整个程序中将其视为常量
不要忘记使用final和variable作为公共或受保护而不是私有,否则你无法从该类外部访问它
答案 6 :(得分:0)
大多数可读解决方案正在使用Static Import。然后,不需要使用AnotherClass.constant
。
编写一个常量为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;
}
}
要了解有关静态导入的详情,请参阅this stack overflow question。
答案 7 :(得分:0)
Java Primitive Specializations Generator支持/* with */
,/* define */
和/* if */ ... /* elif */ ... /* endif */
块,这些块允许用Java代码执行某种宏生成,类似于{中提到的java-comment-preprocessor {3}}。
JPSG具有Maven和Gradle插件。
答案 8 :(得分:0)
Manifold Preprocessor专为Java源代码的条件编译 设计。它使用熟悉的C / C ++风格的指令:#define,#undef,#if,#elif,#else,#endif,#error。和#warning。
它具有Maven和Gradle插件。