#在Java中定义

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1927107/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 01:30:30  来源:igfitidea点击:

#define in Java

javapreprocessorc-preprocessor

提问by Meir

I'm beginning to program in Java and I'm wondering if the equivalent to the C++ #defineexists.

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

A quick search of google says that it doesn't, but could anyone tell me if something similar exists in Java? I'm trying to make my code more readable.

快速搜索谷歌说它没有,但谁能告诉我 Java 中是否存在类似的东西?我正在努力使我的代码更具可读性。

Instead of myArray[0]I want to be able to write myArray[PROTEINS]for example.

而不是myArray[0]我希望能够写作myArray[PROTEINS]

采纳答案by Andrzej Doyle

No, because there's no precompiler. However, in your case you could achieve the same thing as follows:

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

class MyClass
{
    private static final int PROTEINS = 0;

    ...

    MyArray[] foo = new MyArray[PROTEINS];

}

The compiler will notice that PROTEINScan never, ever change and so will inline it, which is more or less what you want.

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

Note that the access modifier on the constant is unimportant here, so it could be publicor protectedinstead of private, if you wanted to reuse the same constant across multiple classes.

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

回答by extraneon

static final int PROTEINS = 1
...
myArray[PROTEINS]

You'd normally put "constants" in the class itself. And do note that a compiler is allowed to optimize references to it away, so don't change it unless you recompile all the using classes.

您通常会在类本身中放置“常量”。并且请注意,允许编译器优化对它的引用,因此除非您重新编译所有 using 类,否则不要更改它。

class Foo {
  public static final int SIZE = 5;

  public static int[] arr = new int[SIZE];
}
class Bar {
  int last = arr[Foo.SIZE - 1]; 
}

Edit cycle... SIZE=4. Also compile Barbecause you compiler may have just written "4" in the last compilation cycle!

编辑循环... SIZE=4。还要编译,Bar因为您的编译器可能在上一个编译周期中刚刚写了“4”!

回答by notnoop

Java doesn't have a general purpose definepreprocessor directive.

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

In the case of constants, it is recommended to declare them as static finals, like in

在常量的情况下,建议将它们声明为static finals,如

private static final int PROTEINS = 100;

Such declarations would be inlined by the compilers (if the value is a compile-time constant).

此类声明将由编译器内联(如果该值是编译时常量)。

Please note also that public static final constant fields are part of the public interface and their values shouldn't change (as the compiler inlines them). If you do change the value, you would need to recompile all the sources that referenced that constant field.

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

回答by Kevin Brock

Comment space too small, so here is some more information for you on the use of static final. As I said in my comment to the Andrzej's answer, only primitive and Stringare compiled directly into the code as literals. To demonstrate this, try the following:

评论空间太小,所以这里有更多关于static final. 正如我在对Andrzej 的回答的评论中所说的那样,只有原始的并且String作为文字直接编译到代码中。为了证明这一点,请尝试以下操作:

You can see this in action by creating three classes (in separate files):

您可以通过创建三个类(在单独的文件中)来查看此操作:

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);
    }
}

Compile these and run Test, which prints:

编译这些并运行测试,它打印:

Int    = 0
Value  = A

Now, change Constantsto have a different value for each and just compile class Constants. When you execute Testagain (without recompiling the class file) it still prints the old value for INT_VALUEbut not VALUE. For example:

现在,更改Constants为每个值都有不同的值,然后编译 class Constants。当您Test再次执行(不重新编译类文件)时,它仍会打印旧值,INT_VALUE但不会打印VALUE. 例如:

public class Constants {
    public static final int INT_VALUE = 2;
    public static final DisplayValue VALUE = new DisplayValue("X");
}

Run Test without recompiling Test.java:

无需重新编译即可运行测试Test.java

Int    = 0
Value  = X

Note that any other type used with static finalis kept as a reference.

请注意,使用 with 的任何其他类型static final都保留为参考。

Similar to C/C++ #if/#endif, a constant literal or one defined through static finalwith primitives, used in a regular Java ifcondition and evaluates to falsewill cause the compiler to strip the byte code for the statements within the ifblock (they will not be generated).

类似于 C/C++ #if/ #endif,常量文字或通过static final原语定义的常量文字,在常规 Javaif条件中使用并计算为false将导致编译器剥离if块内语句的字节码(它们不会生成)。

private static final boolean DEBUG = false;

if (DEBUG) {
    ...code here...
}

The code at "...code here..." would not be compiled into the byte code. But if you changed DEBUGto truethen it would be.

“...code here...”处的代码不会被编译成字节码。但如果你改变了DEBUGtrue那就是了。

回答by Jitendra Nagar

Simplest Answer is "No Direct method of getting it because there is no pre-compiler"But you can do it by yourself. Use classes and then define variables as finalso that it can be assumed as constant throughout the program
Don't forget to use final and variable as public or protected not private otherwise you won't be able to access it from outside that class

最简单的答案是“没有直接获取它的方法,因为没有预编译器”但是您可以自己完成。使用类,然后将变量定义为final,以便在整个程序中将其假定为常量
不要忘记将 final 和变量用作 public 或 protected 而非 private 否则您将无法从该类外部访问它

回答by Md. Abu Nafee Ibna Zahid

Most readablesolution is using Static Import. Then you will notneed to use AnotherClass.constant.

易读的解决方案是使用Static Import。然后,你将不会需要使用AnotherClass.constant

Write a class with the constant as public staticfield.

用常量作为public static字段编写一个类。

package ConstantPackage;

public class Constant {
    public static int PROTEINS = 1;
}

Then just use Static Importwhere you need the constant.

然后只需在需要常量的地方使用静态导入

import static ConstantPackage.Constant.PROTEINS;

public class StaticImportDemo {

    public static void main(String[]args) {

        int[] myArray = new int[5];
        myArray[PROTEINS] = 0;

    }
}

To know more about Static Import please see this stack overflow question.

要了解有关静态导入的更多信息,请参阅此堆栈溢出问题

回答by Igor Maznitsa

There is preprocessor for Javawhich provides directives like #define, #ifdef, #ifndef and many others, for instance PostgresJDBC team uses it to generate sources for different cases and to not duplicate code.

预处理器为Java提供的指令一样的#define,#ifdef来,的#ifndef和其他许多人,例如PostgresJDBC团队使用它来生成不同的案件,不重复的代码源。

回答by leventov

Java Primitive Specializations Generatorsupports /* with */, /* define */and /* if */ ... /* elif */ ... /* endif */blocks which allow to do some kind of macro generation in Java code, similar to java-comment-preprocessor mentioned in this answer.

Java Primitive Specializations Generator支持/* with */,/* define *//* if */ ... /* elif */ ... /* endif */允许在 Java 代码中生成某种宏的块,类似于本答案中提到的 java-comment-preprocessor 。

JPSG has Maven and Gradle plugins.

JPSG 有 Maven 和 Gradle 插件。