簡體   English   中英

#在Java中定義

[英]#define in Java

我開始用 Java 編程,我想知道是否存在與 C++ #define等效的代碼。

快速搜索谷歌說它沒有,但誰能告訴我 Java 中是否存在類似的東西? 我正在努力使我的代碼更具可讀性。

例如,我希望能夠編寫myArray[PROTEINS]而不是myArray[0]

不,因為沒有預編譯器。 但是,在您的情況下,您可以實現以下相同的目標:

class MyClass
{
    private static final int PROTEINS = 0;

    ...

    MyArray[] foo = new MyArray[PROTEINS];

}

編譯器會注意到PROTEINS永遠不會改變,因此會內聯它,這或多或少是你想要的。

請注意,常量上的訪問修飾符在這里並不重要,因此如果您想在多個類中重用相同的常量,它可以是publicprotected而不是私有的。

評論空間太小,所以這里有一些關於使用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);
    }
}

編譯這些並運行測試,它打印:

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那就是。

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

您通常會在類本身中放置“常量”。 並且請注意,允許編譯器優化對它的引用,因此除非您重新編譯所有 using 類,否則不要更改它。

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;

此類聲明將由編譯器內聯(如果該值是編譯時常量)。

另請注意,公共靜態最終常量字段是公共接口的一部分,它們的值不應更改(因為編譯器將它們內聯)。 如果確實更改了該值,則需要重新編譯引用該常量字段的所有源。

Java 的預處理器提供#define、#ifdef、#ifndef 等指令,例如 PostgresJDBC 團隊使用它為不同情況生成源代碼,而不是重復代碼。

易讀的解決方案是使用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;

    }
}

要了解有關靜態導入的更多信息,請參閱此堆棧溢出問題

作為 javac 編譯器插件實現的Manifold PreprocessorJava 源代碼的條件編譯而設計。 它使用熟悉的 C/C++ 風格的指令:#define、#undef、#if、#elif、#else、#endif、#error。 和#警告。

它有 Maven 和 Gradle 插件。

最簡單的答案是“沒有直接獲取它的方法,因為沒有預編譯器”但是您可以自己完成。 so that it can be assumed as constant throughout the program使用類,然后將變量定義為以便在整個程序中將其假定為常量
不要忘記使用 final 和 variable 作為 public 或 protected 不是 private 否則你將無法從該類之外訪問它

Java Primitive Specializations Generator支持/* with *//* define *//* if */ ... /* elif */ ... /* endif */塊,它們允許在 Java 中進行某種宏生成代碼,類似於這個答案中提到的 java-comment-preprocessor 。

JPSG 有 Maven 和 Gradle 插件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM