79

私はJavaでプログラミングを始めていますが、C++に相当するもの#defineが存在するかどうか疑問に思っています。

グーグルをすばやく検索すると、そうではないと言われていますが、Javaに同様のものが存在するかどうか誰かに教えてもらえますか?コードを読みやすくしようとしています。

代わりに、例えばmyArray[0]書くことができるようになりたいです。myArray[PROTEINS]

4

9 に答える 9

107

いいえ、プリコンパイラがないためです。ただし、あなたの場合、次のように同じことを達成できます。

class MyClass
{
    private static final int PROTEINS = 0;

    ...

    MyArray[] foo = new MyArray[PROTEINS];

}

コンパイラーはPROTEINS、それが決して変更できないことに気付くので、それをインライン化します。これは、多かれ少なかれあなたが望むものです。

定数のアクセス修飾子はここでは重要ではないため、複数のクラスで同じ定数を再利用する場合は、プライベートにすることも、プライベートにすることpublicもできます。protected

于 2009-12-18T09:00:59.700 に答える
45

コメント スペースが小さすぎるため、 の使用に関する詳細情報を以下に示しますstatic finalAndrzej's answerへのコメントで述べたように、プリミティブのみでありString、リテラルとしてコードに直接コンパイルされます。これを実証するには、次のことを試してください。

3 つのクラスを (別々のファイルで) 作成することで、これを実際に確認できます。

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それぞれに異なる値を設定し、 class をコンパイルするだけに変更します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プリミティブを使用して定義されたリテラルは、通常の Javaif条件で使用され、 に評価されfalse、コンパイラがブロック内のステートメントのバイト コードを削除しますif(それらは生成されません)。

private static final boolean DEBUG = false;

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

「...code here...」のコードは、バイトコードにコンパイルされません。しかし、あなたがそれに変わっDEBUGたならtrue、それはそうなるでしょう.

于 2009-12-18T09:44:18.910 に答える
6
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」を書き込んだ可能性があるため、コンパイルしてください。

于 2009-12-18T09:00:14.183 に答える
4

Javaには、汎用のdefineプリプロセッサディレクティブはありません。

定数の場合は、次のstatic finalsように宣言することをお勧めします。

private static final int PROTEINS = 100;

このような宣言は、コンパイラーによってインライン化されます(値がコンパイル時定数の場合)。

また、public static final定数フィールドはpublicinterfaceの一部であり、それらの値は変更されるべきではないことにも注意してください(コンパイラーがそれらをインライン化するため)。値を変更する場合は、その定数フィールドを参照するすべてのソースを再コンパイルする必要があります。

于 2009-12-18T09:00:19.190 に答える
0

Java Primitive Specializations Generatorは、この回答で言及されている java-comment-preprocessor と同様に、Java コードである種のマクロ生成を可能にする/* with *//* define */およびブロックをサポートしています。/* if */ ... /* elif */ ... /* endif */

JPSG には Maven および Gradle プラグインがあります。

于 2019-04-08T18:44:14.157 に答える