简体   繁体   English

#在Java中定义

[英]#define in Java

I'm beginning to program in Java and I'm wondering if the equivalent to the C++ #define exists.我开始用 Java 编程,我想知道是否存在与 C++ #define等效的代码。

A quick search of google says that it doesn't, but could anyone tell me if something similar exists in Java?快速搜索谷歌说它没有,但谁能告诉我 Java 中是否存在类似的东西? I'm trying to make my code more readable.我正在努力使我的代码更具可读性。

Instead of myArray[0] I want to be able to write myArray[PROTEINS] for example.例如,我希望能够编写myArray[PROTEINS]而不是myArray[0]

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 PROTEINS can 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 public or protected instead of private, if you wanted to reuse the same constant across multiple classes.请注意,常量上的访问修饰符在这里并不重要,因此如果您想在多个类中重用相同的常量,它可以是publicprotected而不是私有的。

Comment space too small, so here is some more information for you on the use of static final .评论空间太小,所以这里有一些关于使用static final更多信息。 As I said in my comment to the Andrzej's answer , only primitive and String are compiled directly into the code as literals.正如我在对Andrzej 的回答的评论中所说的那样,只有原语和String作为文字直接编译到代码中。 To demonstrate this, try the following:为了证明这一点,请尝试以下操作:

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 Constants to have a different value for each and just compile class Constants .现在,将Constants更改为每个都有不同的值,然后编译类Constants When you execute Test again (without recompiling the class file) it still prints the old value for INT_VALUE but not VALUE .当您再次执行Test (不重新编译类文件)时,它仍会打印INT_VALUE的旧值,但不会打印VALUE For example:例如:

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 final is kept as a reference.请注意,与static final一起使用的任何其他类型都保留为引用。

Similar to C/C++ #if / #endif , a constant literal or one defined through static final with primitives, used in a regular Java if condition and evaluates to false will cause the compiler to strip the byte code for the statements within the if block (they will not be generated).与 C/C++ #if / #endif类似,常量文字或通过带有原语的static final定义的常量文字,在常规 Java if条件中使用并计算为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. “...code here...”处的代码不会被编译成字节码。 But if you changed DEBUG to true then it would be.但是,如果您将DEBUG更改为true那就是。

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 .编辑周期... SIZE=4 Also compile Bar because you compiler may have just written "4" in the last compilation cycle!也编译Bar因为你的编译器可能在上一个编译周期中刚刚写了“4”!

Java doesn't have a general purpose define preprocessor 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.如果确实更改了该值,则需要重新编译引用该常量字段的所有源。

Java 的预处理器提供#define、#ifdef、#ifndef 等指令,例如 PostgresJDBC 团队使用它为不同情况生成源代码,而不是重复代码。

Most readable solution is using Static Import .易读的解决方案是使用Static Import Then you will not need to use AnotherClass.constant .然后,你将不再需要使用AnotherClass.constant

Write a class with the constant as public static field.使用常量作为public static字段编写一个类。

package ConstantPackage;

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

Then just use Static Import where 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 .要了解有关静态导入的更多信息,请参阅此堆栈溢出问题

Manifold Preprocessor implemented as a javac compiler plugin is designed exclusively for conditional compilation of Java source code.作为 javac 编译器插件实现的Manifold PreprocessorJava 源代码的条件编译而设计。 It uses familiar C/C++ style of directives: #define, #undef, #if, #elif, #else, #endif, #error.它使用熟悉的 C/C++ 风格的指令:#define、#undef、#if、#elif、#else、#endif、#error。 and #warning.和#警告。

It has Maven and Gradle plugins.它有 Maven 和 Gradle 插件。

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 final so that it can be assumed as constant throughout the program使用类,然后将变量定义为final,以便在整个程序中将其假定为常量
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 和 variable 作为 public 或 protected 不是 private 否则你将无法从该类之外访问它

Java Primitive Specializations Generator supports /* 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 插件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM