Java中的#define

时间:2009-12-18 08:58:52

标签: java preprocessor c-preprocessor

我开始用Java编程,我想知道是否存在与C ++ #define相当的东西。

快速搜索谷歌说它没有,但任何人都可以告诉我是否存在类似的东西 在Java? 我正在尝试让我的代码更具可读性。

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

9 个答案:

答案 0 :(得分:88)

不,因为没有预编译器。但是,在您的情况下,您可以实现以下相同的目的:

class MyClass
{
    private static final int PROTEINS = 0;

    ...

    MyArray[] foo = new MyArray[PROTEINS];

}

编译器会注意到PROTEINS永远不会改变,所以会内联它,这或多或少都是你想要的。

请注意,常量上的访问修饰符在这里并不重要,因此如果您想在多个类中重复使用相同的常量,那么它可以是publicprotected而不是私有。

答案 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)

作为Javac编译器插件实现的

Manifold Preprocessor专为Java源代码的条件编译 设计。它使用熟悉的C / C ++风格的指令:#define,#undef,#if,#elif,#else,#endif,#error。和#warning。

它具有Maven和Gradle插件。