null
値とis
演算子
前の章で、参照型の変数は特定のオブジェクトを参照する必要はないことを学んだ。
参照型である上記のvariable
には識別子があるが、まだどのオブジェクトも参照していない。このようなオブジェクトは、次の図のようにメモリ内の場所にあると想像することができる。
variable ───┬──────┬─── │ null │ ───┴──────┴───
値を参照しない参照は、null
である。これについては、以下で詳しく説明する。
このような変数はほぼ無用の状態である。参照するMyClass
オブジェクトが存在しないため、実際のMyClass
オブジェクトが必要な文脈では使用できない:
use()
が受け取るパラメーターが参照するオブジェクトが存在しないため、存在しないオブジェクトのメンバにアクセスしようとすると、プログラムがクラッシュする:
"セグメンテーションフォールト"は、不正なメモリアドレスにアクセスしようとしたために、オペレーティングシステムによってプログラムが終了したことを示している。
null
の値
特別な値null
は、他の値と同じように表示できる。
出力:
null
null
変数は、次の2つの文脈でのみ使用できる:
- オブジェクトを代入する
上記の代入により、
variable
は新しく構築されたオブジェクトへのアクセスを提供する。この時点から、variable
は、MyClass
型の有効な操作に使用できる。 null
であるかどうかを判断する。ただし、
==
演算子は比較する実際のオブジェクトを必要とするため、以下の式はコンパイルできない。そのため、変数が
null
であるかどうかは、is
演算子によって決定する必要がある。
is
演算子
この演算子は、"null値を持つか"という質問に答える。
is
は、他の型の変数にも使用できる。以下の使用例では、2つの整数のvalues
を比較している。
スライスと組み合わせて使用すると、2つのスライスが同じ要素のセットを参照しているかどうかを判断する:
!is
演算子
!is
は、is
の逆である。値が異なる場合、true
を返す。
null
の値の代入
null
の値を参照型変数に代入すると、その変数は現在のオブジェクトへの参照を停止する。
その代入が実際のオブジェクトへの最後の参照を終了させる場合、実際のオブジェクトはガベージコレクタによる最終化の対象となる。結局、どの変数からも参照されていないオブジェクトは、プログラム内で使用されていないことになる。
前の章で、2つの変数が同じオブジェクトを参照していた例を見てみよう。
以下の図は、そのコードを実行した後のメモリの状態を表している:
(anonymous MyClass object) variable variable2 ───┬───────────────────┬─── ───┬───┬─── ───┬───┬─── │ ... │ │ o │ │ o │ ───┴───────────────────┴─── ───┴─│─┴─── ───┴─│─┴─── ▲ │ │ │ │ │ └────────────────────┴────────────┘
null
の値をこれらの変数の1つに代入すると、その変数とオブジェクトとの関係が切断される。
この時点では、MyClass
オブジェクトを参照しているのはvariable2
だけになる:
(anonymous MyClass object) variable variable2 ───┬───────────────────┬─── ───┬────┬─── ───┬───┬─── │ ... │ │null│ │ o │ ───┴───────────────────┴─── ───┴────┴─── ───┴─│─┴─── ▲ │ │ │ └──────────────────────────────────┘
最後の参照にnull
を代入すると、MyClass
オブジェクトが到達不能になる:
このような到達不能なオブジェクトは、将来のどこかの時点でガベージコレクタによって破棄される。プログラムの観点からは、オブジェクトは存在しないことになる:
variable variable2 ───┬───────────────────┬─── ───┬────┬─── ───┬────┬─── │ │ │null│ │null│ ───┴───────────────────┴─── ───┴────┴─── ───┴────┴──
関連配列の章の演習セクションで、関連配列を空にする方法について議論した。現在、4つ目の方法を知っている:null
を関連配列変数に代入すると、その変数と要素の関係が切断される:
MyClass
の例と同様に、names
が連想配列の要素への最後の参照であった場合、それらの要素はガベージコレクタによって最終化される。
スライスにもnull
を代入できる:
要約
null
は、変数がどの値にもアクセスできないことを示す値である。null
値を持つ参照は、2つの操作(値への代入と、null
であるかどうかの判定)でのみ使用できる。==
演算子は実際のオブジェクトにアクセスする必要があるため、変数がnull
であるかどうかを判断するには、is
演算子を使用する必要がある!is
は、is
- 変数に
null
を代入すると、その変数は何も参照しなくなる - 変数によって参照されていないオブジェクトは、ガベージコレクタによって破棄される