# 用 Java 定义

我开始用 Java 编程,我想知道是否存在与 C + + #define等价的程序。

在谷歌上快速搜索一下就会发现并非如此,但有人能告诉我是否存在类似的情况吗 在爪哇? 我想让我的代码更易读。

例如,我希望能够编写 myArray[PROTEINS]而不是 myArray[0]

214246 次浏览
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”在上一个编译周期!

Java 没有通用的 define预处理器指令。

对于常量,建议将它们声明为 static finals,如

private static final int PROTEINS = 100;

这样的声明将由编译器内联(如果值是编译时常量)。

还请注意,公共静态 final 常量字段是公共接口的一部分,它们的值不应该更改(因为编译器将其内联)。如果更改了该值,则需要重新编译引用该常量字段的所有源。

不,因为没有预编译器。然而,在你的情况下,你可以实现如下相同的事情:

class MyClass
{
private static final int PROTEINS = 0;


...


MyArray[] foo = new MyArray[PROTEINS];


}

编译器将注意到 PROTEINS永远不会改变,因此将内联它,这或多或少是您想要的。

请注意,常量上的访问修饰符在这里并不重要,因此如果您想在多个类之间重用同一个常量,它可以是 publicprotected,而不是 private。

注释空间太小,所以这里有一些关于使用 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...
}

“ ... code here...”中的代码不会被编译成字节码。但是如果你把 DEBUG改成 true,那么它就是。

最简单的答案是 < B > “ No Direct method of get it because there is No pre-Editor” 但你可以自己来。使用类,然后将变量定义为 最终,这样它就可以在整个程序中被假定为常量
不要忘记使用 final 和 variable 作为 public 或 protected 而不是 private,否则您将无法从该类之外访问它

大多数 可读解决方案是使用 静态进口。那么你将 没有需要使用 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;


}
}

要了解更多关于静态进口请参阅 这个堆栈溢出问题

有一个 用于 Java 的预处理程序提供了类似 # Definition,# ifdef,# ifndef 和许多其他指令,例如 PostgreJDBC 团队使用它为不同的情况生成源代码,并且不会重复代码。

Java 原始专门化生成器 支持 /* with *//* define *//* if */ ... /* elif */ ... /* endif */块,这些块允许在 Java 代码中执行某种宏生成,类似于 这个答案中提到的 Java 注释预处理器。

JPSG 有 Maven 和 Gradle 插件。

流形预处理器 作为 javac 编译器插件实现,是专门设计的 Java 源代码的 条件编译。它使用熟悉的 C/C + + 风格的指令: # Definition,# undef,# if,# elif,# else,# endf,# error。# 警告。

它有 Maven 和 Gradle 插件。