プリミティブの明示的な初期化

Javaプリミティブにはデフォルトの初期化値があることを理解しています。たとえば int の場合は 0 です。

私の研究から、私はこれらの価値に頼るべきではないと思われます。私はいつも明示的な初期化を提供するべきですか?もしそうなら、どこで?

私のプログラムの一部です:

public class Calculator {

// Initialize value where it's declared?
private int value;

public Calculator() {
   //Initialize value in constructor?
}

public void add(int other) {
    value += other;
}
}
9
「私の研究から、私はこれらの価値に頼るべきではないようです。言語仕様では信頼できるソースが不十分ですか?
追加された 著者 fge,
基本値を必要とせず、論理的には、クラスのすべてのインスタンスでインスタンス変数を少なくとも特定の値に設定する必要がある場合は、コンストラクタを使用できます。
追加された 著者 NINCOMPOOP,
それは、値に頼ることと、他のプログラマーにあなたが使っている価値を明示することについて、それほど重要ではありません。
追加された 著者 Boris the Spider,

7 答え

Javaによって生成されたデフォルト値を使用することはまったく問題ですが、クラスのインスタンスまたは static フィールドを明示的に初期化する必要はありません。 Java言語仕様はこれを必要とするため、言語の実装はすべて準拠する必要があります。つまり、メンバ変数のデフォルト値を使用すると、コードは100%移植可能なままになります。これはプリミティブ型と参照型の両方に適用されます(後で null で初期化されます)。

詳細は、 Java言語仕様(81ページ)を参照してください。

4.12.5変数の初期値

     

プログラム内のすべての変数は、その値が使用される前に値を持たなければなりません:    - 各クラス変数、インスタンス変数、または配列コンポーネントは、aで初期化されます。   作成時のデフォルト値

明示的な初期化を行う必要がある唯一のケースは、ローカル変数を宣言する場合です。

ローカル変数は、初期化または割り当てによって、使用前に明示的に値を与えて、明確な割り当ての規則を使って検証することができるようにする必要があります。

ただし、ローカルを初期化できないとコンパイル時エラーとなるため、コンパイラはプログラムを実行する前に、すべての不足している初期化を特定します。

4
追加された

私の研究から、私はこれらの価値に頼るべきではないと思われます。

あなたはそれらに頼ることができます。既に知っているように、デフォルトで行われるので、害はありません。

私はいつも明示的な初期化を提供するべきですか?もしそうなら、どこで?

プリミティブの場合、明示的な初期化を行う必要はありません。私はめったにインスタンス変数のような int i = 0; のような初期化を行う人はいません。しかし、あなたがローカル変数について話しているなら、明示的な値を与える必要があります。デフォルトはそこに暗黙的ではありません。

しかし、非プリミティブの場合は、値がデフォルトで null であるため、宣言の時点またはコンストラクタ内で明示的な初期化を行う必要があります。コード> NPE を参照してください。宣言の時点で初期化することの利点は、各コンストラクタに初期化を行う必要がないことです。

1
追加された
デフォルトまたは「ダミー」変数でローカル変数を初期化しないでください。これは、コンパイラによって実行された静的解析を妨げ、見落としたコードパスを警告する可能性があります。たとえば、ローカル変数を宣言し、値を割り当てずに後で読み込むと、コンパイラによって警告が表示されます。無意味なデフォルト値で初期化した場合、コンパイラはあなたのバグを検出しません。したがって、宣言を空白のままにしておくか、変数を宣言してから実際の値を初期化するまで待ってください。
追加された 著者 erickson,
@erickson。ええ、その通り。実際には、私はそれを意味しました。必要に応じて、ローカル変数を宣言することをお勧めします。これは、あなたが奇妙な問題を抱えているときに、多くの作業を節約します。
追加された 著者 Rohit Jain,

原則として、あなたが書いたコードは、常に最も驚くべきことを実行する必要があります。明示的に初期化されていない変数のデフォルト値0が驚異的だと感じる場合は、おそらく、ゼロであっても常に初期値を割り当てるようにしてください。

表示されたコードの私の個人的な好みは、宣言された変数を0に初期化することです。これは単に変数の最初の操作が + = であり、数値操作のデフォルト値に頼っているのが間違っているからです。それはちょうどそれが間違っているので、うまくいくので、これには正当な理由はありません。

0
追加された

メンバー変数はデフォルト値で初期化されます。だからあなたはそれについて心配する必要はありません。しかし、デフォルト値やその他の値で初期化したい場合は、コンストラクタで設定することもできます

0
追加された
コンストラクタなし:public class A {public int num = 2; public void A(){}}
追加された 著者 Ramin Darvishov,
そうかも知れない。私はちょうど他の方法を提供する
追加された 著者 Ramin Darvishov,
コンストラクタで初期化するほうが良いです。
追加された 著者 stinepike,
それは良いです、私は私の答えは、コンストラクタで初期化するためのdownvoteを持っていると思った:)
追加された 著者 stinepike,

本当に心配している場合は、コンストラクタの変数を初期化してください。しかし、ゼロ以外の値に初期化された数値プリミティブは見たことがありません。

私はあなたがカスタム(および劣悪な)JVMで作業していた場合、これについて心配する必要があると思います。

0
追加された

デフォルト値は信頼できるものです。


実際には、他のすべてのアクションの前に、デフォルトの割り当てが行われるため、明示的なゼロ調整よりも「信頼できる」ものです。

0
追加された

デフォルト値でJVMプリミティブの初期化を明確に信頼できます。


ところで、明示的な初期化は、この場合は役に立たないバイトコードに変換されます。

このクラスがあるとします:

public class PrimitiveInitialization {
    int i = 0;
    int j;
}

対応するバイトコードは

class PrimitiveInitialization {
  I i
  I j

  public ()V
   L0
    LINENUMBER 8 L0
    ALOAD 0
    INVOKESPECIAL java/lang/Object. ()V
   L1
    LINENUMBER 10 L1
    ALOAD 0
    ICONST_0
    PUTFIELD PrimitiveInitialization.i : I
    RETURN
   L2
    LOCALVARIABLE this LPrimitiveInitialization; L0 L2 0
    MAXSTACK = 2
    MAXLOCALS = 1
}

明示的な初期化では、変数 i にバイトコード操作がほとんど追加されないことがわかります。

つまり、JITは実行時にこの種のバイトコードをおそらく最適化できるため、常にコードの可読性を優先する必要があります

0
追加された