nullに割り当てられた変数と割り当てられていない変数のメモリの違いは何ですか?
使用方法に違いがあることは知っていますが、メモリの違いは何ですか?
nullに割り当てられた変数と割り当てられていない変数のメモリの違いは何ですか?
使用方法に違いがあることは知っていますが、メモリの違いは何ですか?
回答:
「メモリ内」の2つの間に違いはありません。
プログラム内のすべての変数には、その値が使用される前に値が必要です。
- 各クラス変数、インスタンス変数、または配列コンポーネントは、作成時にデフォルト値で初期化されます(§15.9、§15.10.2):
...
- すべての参照タイプ(4.3)では、デフォルト値はnullです。
...
- ローカル変数(§14.4、§14.14)は、使用前に、初期化(§14.4)または割り当て(§15.26)によって、明確な割り当てのルールを使用して検証できる方法で、明示的に値を指定する必要があります(§ 16(明確な割り当て))。
クラスまたはオブジェクトレベルの参照変数にはnull値が割り当てられます。
メソッド(スタック)レベルの参照変数は、(C ++用語を使用して)未指定の値になります。実際にはこれは多くの場合nullですが、標準では参照変数の内容を指定していません。使用する前に割り当てる必要があることだけを指定しています。スタック上の参照変数を最初の使用として割り当て以外の方法で使用すると、コンパイルエラーが発生します。
if-then
ブロック内で初期化すると、then
ブロックが実行されない場合、コードの前で変数が初期化されていない可能性があることがコンパイラーから通知されます。初期化するとnull
コードがコンパイルされます。「明示的に値が割り当てられていない参照が値nullを持っている」とすると、それはなぜですか?
null
。これを行うのは不必要な作業なので、初期化する必要はありません。
nullに割り当てられた変数とメモリに割り当てられていない他の変数の違いは何ですか?
Javaには、割り当てられていない変数などはありません。明示的な割り当てがないクラスデータメンバーには、型のデフォルト値、オブジェクトのnull、またはプリミティブ型の0に似たものが割り当てられます。
ローカル変数はスタック上にあります。(MyType foo
参照として、スタック上にも存在するような非プリミティブローカル)スタックの割り当ては単純です。ブロックにローカル変数の宣言が含まれている場合、それらのローカル変数に必要なスペースはスタック上に予約されます。スタックを調整してそれらのローカル変数に対応する際に、それらのローカル変数に値を割り当てるかどうかは関係ありません。
重要ではない理由は、実行がブロックに入るときにローカル変数に値が割り当てられているかどうかが2つあるためです。1つの理由は、必要なサイズが変化しないことです。プリミティブのサイズは固定されており、非プリミティブは実際には参照です。(参照されるオブジェクトは、スタックではなくヒープ上に存在します。)2番目の理由は、値が割り当てられていないローカル変数を使用すると、コンパイルエラーが発生するためです。これにより、宣言されているが割り当てられていないローカル変数に値(必ずしもデフォルトではない)を与えるかどうかは、Javaランタイム次第です。
if-then
ブロック内で初期化すると、then
ブロックが実行されない場合、コードの前で変数が初期化されていない可能性があるとコンパイラーは伝えます。初期化するとnull
コードがコンパイルされます。「明示的に値が割り当てられていない参照が値nullを持っている」とすると、それはなぜですか?しかし、それは私にはまだ十分に明確ではありません。言い換えれば、それを説明できますか?
null
。これにより、Javaデバッガの開発が大幅に簡素化されます。しかし、デバッグを無効にしてコンパイルするとどうなるでしょうか。これで、初期化は不要な余分な作業です。メモリーには最初の使用時に有効な値が含まれることがわかっているため、そのメモリーの内容は無関係です。
まず、ローカル変数が使用するスペースについて心配する必要はありません。1行で100,000整数の配列を割り当てることができます。これは、これから使用するすべてのローカル変数よりも多くのスペースを必要とします。
第二に、あなたのコードは賢い可能性が高いコンパイラによってコンパイルされます。変数が初期化されていない場合、それは使用されません(コンパイラーが初期化されていない変数の使用を許可していないため)。しかし、それをnilに初期化しても、まだ使用されていません。コンパイラーは、それが使用されておらず、実際には変数にスペースをまったく使用していないことを容易に理解します。これを使用しても、コンパイラは値がnilであることを簡単に判断し、変数の代わりにnilを使用します。
しかし、3番目に、これはすべてプログラムを最適化するのに役立つわけではないすべてのマイクロ最適化です。4バイトまたは8バイトを保存しようとしています。何かを保存したい場合は、メガバイトの節約に集中してください。
そして最後に、変数を常に初期化する必要があると主張する人もいますが、Javaではそうではありません。変数には意味のある値のみを設定してください。変数に人物の名前を設定したいとし、1つのコードパスでこれを行うのを忘れたとします。変数を盲目的にnilに初期化すると、コンパイラーはそれを通知できません。初期化を行わない場合、コンパイラは間違いを教えてくれます。