「nullを代入することにより参照を切る」という動作はどのような場面で利用されるのか?メモリの様子は?
解決したいこと
Javaの基本について再学習している者です。
質問したいことは
- タイトルのとおり、 「nullを代入することにより参照を切る」 という動作について2点
- String型変数は参照型変数ではないのか?(できればご教示いただけると幸いです)
の計3点あります。
以下で詳しく説明いたします。
5/10、コード内容と日本語を一部訂正しました。
「参照を切る」ということへの現時点での理解
null
について学習をしていた際、
nullとは「何もない」という意味で、配列変数aのような参照型の変数に代入することができます。nullが代入されると、参照型の変数はどこも参照していない状態になります。
という記載が書籍1にありました。
例として以下のようなコードがあるとします。
public class Main
public static void main (String args[]){
int [] a = {1, 2, 3};
int [] b = a;
b = null; //参照を切った。
System.out.println("~配列a~");
for(int x:a){
System.out.println(x);
}
}
}
この表示結果が以下のようになります。
~配列a~
1
2
3
~配列b~
Exception in thread "main" java.lang.NullPointerException: Cannot read the array length because "<local3>" is null
at Main.main(Main.java:15)
質問1
しかし、配列の「参照を切る」というこの動作は、実際にどのような場面で利用されるのか全くイメージが湧きません。
GCがあるにも関わらず、わざわざ変数の初期化の必要がある場面はどのような時起こるのでしょうか?
質問2
2つ目の質問は参照を切られた後のメモリの様子についてです。
上記コードが動いた場合、配列aが初期化されたint[] a = {1, 2, 3};
の時点で配列a用のメモリ区画が用意されたと思います。
そしてint[] b = a;
の時点で、そのメモリ区画のアドレスを配列bが参照しているという状態だと思います。
では、配列bの参照が切られた後に、
新しく配列bに値が代入されたb[0] = 10;
の時点で、配列b用のメモリ区画が新しく用意された
配列bにはメモリ区画が一切割り当てられていない、という認識で正しいでしょうか?
その場合この後配列bを(数値を代入するなどして)利用することは全くできないのでしょうか?
質問3
3つ目の質問は、null
とString
についての質問です。
同様の書籍にnull
について以下のような記載がありました。
int型などの基本型変数には代入することができない。
ところで、null
はString型の変数に代入することができると考えています。
ということは、String型の変数は参照型変数のはずです。
しかし以下のようなコードを動かすと
public class Main{
public static void main (String [] args) {
String a = "あいう";
String b = a; //同じメモリ区画を参照してるはず?
b = "えお"; //aとb両方のメモリ区画の内容を書き換えたはず?
System.out.println(a);
System.out.println(b);
}
}
あいう
えお
という結果になります。
String型変数は参照型変数ではないのでしょうか?
最後に
長文の質問となり失礼いたしました。
どなたか有識な方にご回答いただけると幸いです。
また質問・表記方法や理解などに間違いがあれば、そちらだけでもご指摘いただけると嬉しいです。
よろしくお願いいたします!!!
-
中山清喬, 国本大悟. 『スッキリわかるJava入門第2版』 ↩