[英]#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
永遠不會改變,因此會內聯它,這或多或少是你想要的。
請注意,常量上的訪問修飾符在這里並不重要,因此如果您想在多個類中重用相同的常量,它可以是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);
}
}
編譯這些並運行測試,它打印:
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 Preprocessor專為Java 源代碼的條件編譯而設計。 它使用熟悉的 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.