[解決済み] なぜNullPointerExceptionが発生しないのですか?
質問
以下のコードについて教えてください。
StringBuilder sample = new StringBuilder();
StringBuilder referToSample = sample;
referToSample.append("B");
System.out.println(sample);
これは、以下のように表示されます。
B
と表示されるので
sample
であり
referToSample
オブジェクトは同じメモリ参照を参照します。
StringBuilder sample = new StringBuilder();
StringBuilder referToSample = sample;
sample.append("A");
referToSample.append("B");
System.out.println(referToSample);
これは、以下のように表示されます。
AB
と表示され、これも同じことを証明しています。
StringBuilder sample = new StringBuilder();
StringBuilder referToSample = sample;
referToSample = null;
referToSample.append("A");
System.out.println(sample);
明らかに、これは
NullPointerException
を呼び出そうとしているのですから。
append
を呼び出そうとしているからです。
StringBuilder sample = new StringBuilder();
StringBuilder referToSample = sample;
referToSample = null;
sample.append("A");
System.out.println(sample);
ここで質問ですが、なぜ最後のコードサンプルは
NullPointerException
なぜなら、私が最初の2つの例から見て理解したことは、2つのオブジェクトが同じオブジェクトを参照している場合、何らかの値を変更すると、それはもう一方にも反映されるということです。では、なぜここではそのルールが適用されないのでしょうか?もし私が
null
をreferToSampleに代入すると、sampleもnullになり、NullPointerExceptionが投げられるはずですが、投げられないのはなぜでしょうか?
どのように解決するのですか?
null
割り当てが変更されない
値
をグローバルに破壊することによって変更することはできません。そのような動作は、追跡困難なバグや直感に反する動作につながるでしょう。彼らは、その特定の
参照
.
簡単のために、次のようにしましょう。
sample
はアドレス 12345 を指しているとします。これはおそらくアドレスではなく、ここでは物事を単純にするために使われているだけです。
通常
で与えられる奇妙な 16 進数で表されます。
Object#hashCode()
で表されますが、これは実装に依存します。
1
StringBuilder sample = new StringBuilder(); //sample refers to
//StringBuilder at 12345
StringBuilder referToSample = sample; //referToSample refers to
//the same StringBuilder at 12345
//SEE DIAGRAM 1
referToSample = null; //referToSample NOW refers to 00000,
//so accessing it will throw a NPE.
//The other reference is not affected.
//SEE DIAGRAM 2
sample.append("A"); //sample STILL refers to the same StringBuilder at 12345
System.out.println(sample);
と書かれた行から
See diagram
と書かれた線から、その時のオブジェクトの図は次のようになります。
図1:
[StringBuilder sample] -----------------> [java.lang.StringBuilder@00012345]
↑
[StringBuilder referToSample] ------------------------/
図2:
[StringBuilder sample] -----------------> [java.lang.StringBuilder@00012345]
[StringBuilder referToSample] ---->> [null pointer]
図2は
referToSample
の参照は壊れません。
sample
での StringBuilder への参照は壊れません。
00012345
.
1 GC を考慮すると、これはありえないことです。
関連
-
Eclipse の問題 アクセス制限。タイプ 'jfxrt' はAPI解決されていません。
-
unsigned char* から const jbyte* {aka const signed char*} への変換が無効です。
-
[解決済み] この2回(1927年)を引き算すると、なぜおかしな結果になるのでしょうか?
-
[解決済み] JavaでNullPointerExceptionを回避する方法
-
[解決済み] なぜパスワードにはStringではなくchar[]が好まれるのですか?
-
[解決済み] serialVersionUIDとは何ですか、またなぜそれを使用する必要がありますか?
-
[解決済み] 割り当て後にリストが予期せず変更されました。その理由と防止策を教えてください。
-
[解決済み] B "の印刷が "#"の印刷より劇的に遅いのはなぜですか?
-
[解決済み] ランダムな文字列を使用するこのコードは、なぜ "hello world" と表示されるのですか?
-
[解決済み】なぜJavaの+=, -=, *=, /=複合代入演算子はキャスティングを必要としないのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
undefined[sonar] sonar:デフォルトのスキャンルール
-
javaの非静的メソッドを静的に参照することができない
-
Java の switch case 文で必要な定数式の問題の解決法
-
メモ帳でJavaプログラムをコンパイルして実行すると、Could not find or load main class ...というエラーが表示される。解決方法
-
ブートレイヤーの初期化中にエラーが発生しました java.lang.module.FindException: モジュールが見つかりません
-
名前 'XXX' を持つ Bean の作成に失敗しました。自動依存関係の注入に失敗しました 解決方法
-
JDK8 の Optional.of と Optional.ofNullable メソッドの違いと使い方を説明する。
-
JNIエンカウンターエラー:構造体またはユニオンではない何かでメンバー 'FindClass' のリクエスト
-
Javaがリソースリークに遭遇した:'input'が閉じない 解決方法
-
テストが空であるかどうかを判断するためのオプションの処理