我开始用Java编程,并且想知道是否#define
存在与C ++等效的语言。
谷歌快速搜索说没有,但是有人可以告诉我Java是否存在类似的东西吗?我正在尝试使代码更具可读性。
而不是myArray[0]
我想能够写myArray[PROTEINS]
例如。
Answers:
不,因为没有预编译器。但是,您可以实现以下相同的目的:
class MyClass
{
private static final int PROTEINS = 0;
...
MyArray[] foo = new MyArray[PROTEINS];
}
编译器会注意到PROTEINS
永远不会改变,因此会内联它,这或多或少是您想要的。
请注意,在不断的访问修饰符是不重要的在这里,所以它可能是public
或protected
不是的私人,如果你想重复使用多个类相同的常数。
注释空间太小,因此这里有一些有关的更多信息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
/类似,在常规Java条件中使用#endif
常量常量或static final
使用原语定义的常量常量,if
并求值false
会导致编译器剥离if
块中语句的字节码(不会生成)。
private static final boolean DEBUG = false;
if (DEBUG) {
...code here...
}
“ ...此处的代码...”中的代码不会被编译为字节码。但是,如果您更改DEBUG
为true
,那就可以了。
enum
s的作用不同。
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;
此类声明将由编译器内联(如果该值是编译时常量)。
另请注意,公共静态最终常量字段是公共接口的一部分,并且它们的值不应更改(因为编译器将它们内联)。如果确实更改了该值,则需要重新编译所有引用该常量字段的源。
static finals
并不是真正的公共接口的一部分。:)public static finals
但是,这是事实。
最易读的解决方案是使用静态导入。然后,你将不会需要使用AnotherClass.constant
。
用常量aspublic 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;
}
}
要了解有关静态导入的更多信息,请参见此堆栈溢出问题。
最简单的答案是“因为没有预编译器,所以没有直接获得它的方法”,
但是您可以自己完成。使用类,然后将变量定义为final,这样就可以在整个程序中将其假定为常量
不要忘了将final和变量用作public或protected not private,否则您将无法从该类外部访问它
Java基本专业化发电机支持/* with */
,/* define */
以及/* if */ ... /* elif */ ... /* endif */
块允许这样做在Java代码中某种宏发电,类似于提到的Java注释的预处理这个答案。
JPSG具有Maven和Gradle插件。
作为Javac编译器插件实现的流形预处理器专门用于条件编译Java源代码的。它使用了熟悉的C / C ++风格的指令:#define,#undef,#if,#elif,#else,#endif,#error。和#警告。
它具有Maven和Gradle插件。