Javaオブジェクト指向プログラミング(4) - インスタンスについて覚えておきたいこと

プログラミング、サーバー、ネットワーク、IT用語、ハマったときのトラブルシューティングなど様々なIT関連の話題をひたすら書いていく技術ブログです。

2017年8月17日木曜日

Javaオブジェクト指向プログラミング(4) - インスタンスについて覚えておきたいこと


JavaはJVMが準備したコンピュータのメモリ領域で動きます。このメモリ領域をヒープといいます。Javaのプログラムが例えばインスタンス化するとヒープ領域を使い、インスタンス情報を格納します。つまりインスタンスとはヒープに確保された一部のメモリ領域です。

インスタンス生成で何が起こっているのか?

※このプログラムは完全ではありません。説明するため使用するため最低限の実装しかしていません。



まず、「Samurai s」の部分が実行されると、JVMが使用されていないメモリ(ヒープ)に変数sの準備・領域確保します(例:メモリの20番地)。このときはまだインスタンス化されていないのでSamuraiのインスタンスを受け入れる準備だけされています。インスタンス化はnew Samurai()の部分です。このインスタンス化された情報を格納するためにピープの中でインスタンスのサイズに応じて必要なメモリを確保します (例:100〜130番地)。

ここで変数sに入っているのは何でしょうか?実はインスタンス自体が代入されているわけではなく、インスタンスの確保されたメモリの先頭番地が代入されています。上記の例で言うと100が代入されています。変数sの領域には実際のインスタンス情報はなく、「100番を確認してください」という情報がありますので、実際は100番を参照します。このように他の領域を参照させるモノを参照型と言います。そのあとは、名前を書き換えたらHPを書き換えたりしていますが、まず上記の順番(20番→100番)でアクセスして、name部分やhp部分を書き換えます。

インスタンスは独立している

侍クラスのインスタンスが2回生成され、s1とs2に代入されたとします。s1の侍の名前を変えても当然s2には何も影響がありません。注意が必要な場合は下記のプログラムです。


この結果は「ただの侍」が表示されます。なぜかというと変数の中はメモリの先頭番地が入っているからです。Samurai s2 = s1はs1に入っている番地をs2にコピーしているので、s1もs2も同じ侍ということになります。結果、どちらかの変数で名前やHPを変えるともう片方の変数にも影響があるのです。

has aの関係




上記の侍クラスのプログラムは、刀クラス型のフィールドがありますが、問題ありません。なぜ問題ないかというとhas a(持っている)という英文が成り立ち自然だからです。

Samurai has a Katana.(侍は刀を持っている)

この時もKatanaはメモリがしっかり確保され、変数katanaには刀の情報が確保されているメモリの先頭番地が代入されています。この他フィールド以外にも、メソッドの引数や戻り値にクラス型のフィールドを用いることができます。

◯「Javaオブジェクト指向プログラミング(5) - コンストラクタ」の記事はこちら
◯「Javaオブジェクト指向プログラミング」シリーズの記事一覧はこちら



最近の投稿