先日のプログラムを順に追ってみる

どんな動きをしていたのか、少し追いかけてみることにする。
先日の記事id:regasuie:20060206:1139215946


c:\>java GcQuiz

  1. ClassA型のインスタンス「ジマイマ」を作成、クラス変数「q」より参照
  2. インスタンス変数「r」を宣言。GcQuiz型インスタンスが作成される際にClassA型のインスタンスレベッカ」が作成される
  3. ClassA型のインスタンス「ミトン」を作成、ローカル変数「a」より参照
  4. ClassA型のインスタンス「トム」を作成、ローカル変数「b」より参照
  5. ClassA型のインスタンスモペット」を作成、ローカル変数「c」より参照
  6. ClassB型の配列「arrayA」を宣言、配列要素は4
  7. 変数「b」に変数「c」を代入、これによりインスタンス「トム」はガーベッジとなる
  8. ClassB型のインスタンス「犬0」が作成され、arrayA[0]に代入される
  9. ClassB型のインスタンス「犬1」が作成され、arrayA[1]に代入される
  10. ClassB型のインスタンス「犬2」が作成され、arrayA[2]に代入される
  11. ClassB型のインスタンス「犬3」が作成され、arrayA[3]に代入される
  12. arrayA[3]の変数「friend」にarrayA[3]を代入する
  13. arrayA[0]にarrayA[1]を代入、これによりインスタンス「犬0」はガーベッジとなる
  14. 変数cにarrayA[2]を代入
  15. ClassA型の変数「d」にarrayA[0]を代入
  16. ClassB型の配列「arrayB」を宣言、配列要素は4
  17. ClassB型のインスタンス「プロプシー,ClassA型のインスタンス「野ネズミ」」を作成、arrayB[0]に代入
  18. ClassB型のインスタンス「モプシー,ClassA型のインスタンス「ナトキン」」を作成、arrayB[0]に代入
  19. ClassB型のインスタンス「カトンテール,変数「c」」を作成、arrayB[0]に代入
  20. ClassB型のインスタンス「ピーター,ClassA型のインスタンス「ベンジャミン」」を作成、arrayB[0]に代入
  21. 配列「arrayA」の参照を消去、これによりインスタンス「犬3」はガーベッジとなる
  22. arrayB[0]の変数「friend」の参照を消去、それによりインスタンス「野ネズミ」はガーベッジとなる
  23. arrayB[1]の参照を消去、それによりインスタンス「モプシー」「ナトキン」はガーベッジとなる
  24. arrayB[2]の参照を消去、それによりインスタンス「カトンテール」はガーベッジとなる
  25. ClassB型のインスタンス「ルーシー,ClassA型のインスタンス「ティギー」」を作成、ClassB型の変数eへ代入
  26. 変数eの参照を消去

続けて、ClassA及びClassBのインスタンス作成時の動きも追いかけてみる。

ClassA

  1. String型の引数「name」をインスタンス変数「name」に参照させる
  2. ClassA型のクラス変数「last」に自身のインスタンスを参照させる

ClassB

  1. 引数が1つの場合ClassAのコンストラクタを呼び出し引数を渡す
  2. 引数が2つの場合ClassAのコンストラクタを呼び出しString型の引数を渡し、
  3. インスタンス変数「friend」にClassA型の引数「friend」を参照させる

こんな感じかな? 上記2つを踏まえてもう一度、処理の追跡。

c:\>java GcQuiz

  1. ClassA型のインスタンス「ジマイマ」を作成、クラス変数「q」より参照
    1. String型の引数「"ジマイマ"」をインスタンス変数「name」に参照させる
    2. ClassA型のクラス変数「last」に自身のインスタンス「ジマイマ」を参照させる
  2. インスタンス変数「r」を宣言。GcQuiz型インスタンスが作成される際にClassA型のインスタンスレベッカ」が作成される
    1. 尚、今回のケースではGcQuiz型のインスタンスが作成されることは無い為、「レベッカ」が作成されることは無い
  3. ClassA型のインスタンス「ミトン」を作成、ローカル変数「a」より参照
    1. String型の引数「"ミトン"」をインスタンス変数「name」に参照させる
    2. ClassA型のクラス変数「last」に自身のインスタンス「ミトン」を参照させる
  4. ClassA型のインスタンス「トム」を作成、ローカル変数「b」より参照
    1. String型の引数「"トム"」をインスタンス変数「name」に参照させる
    2. ClassA型のクラス変数「last」に自身のインスタンス「トム」を参照させる
  5. ClassA型のインスタンスモペット」を作成、ローカル変数「c」より参照
    1. String型の引数「"モペット"」をインスタンス変数「name」に参照させる
    2. ClassA型のクラス変数「last」に自身のインスタンスモペット」を参照させる
  6. ClassB型の配列「arrayA」を宣言、配列要素は4
  7. 変数「b」に変数「c」を代入、これによりインスタンス「トム」はガーベッジとなる
  8. ClassB型のインスタンス「犬0」が作成され、arrayA[0]に代入される
    1. ClassAのコンストラクタを呼び出し、String型の引数「"犬0"」をインスタンス変数「name」に参照させる
    2. ClassA型のクラス変数「last」に自身のインスタンス「犬0」を参照させる
  9. ClassB型のインスタンス「犬1」が作成され、arrayA[1]に代入される
    1. ClassAのコンストラクタを呼び出し、String型の引数「"犬1"」をインスタンス変数「name」に参照させる
    2. ClassA型のクラス変数「last」に自身のインスタンス「犬1」を参照させる
  10. ClassB型のインスタンス「犬2」が作成され、arrayA[2]に代入される
    1. ClassAのコンストラクタを呼び出し、String型の引数「"犬2"」をインスタンス変数「name」に参照させる
    2. ClassA型のクラス変数「last」に自身のインスタンス「犬2」を参照させる
  11. ClassB型のインスタンス「犬3」が作成され、arrayA[3]に代入される
    1. ClassAのコンストラクタを呼び出し、String型の引数「"犬3"」をインスタンス変数「name」に参照させる
    2. ClassA型のクラス変数「last」に自身のインスタンス「犬3」を参照させる
  12. arrayA[3]のインスタンス変数「friend」にarrayA[3]を代入する
    1. arrayA[3].friendは「犬3」を参照することになる
  13. arrayA[0]にarrayA[1]を代入、これによりインスタンス「犬0」はガーベッジとなる
  14. 変数cにarrayA[2]を代入
  15. ClassA型の変数「d」にarrayA[0]を代入
  16. ClassB型の配列「arrayB」を宣言、配列要素は4
  17. ClassB型のインスタンス「プロプシー,ClassA型のインスタンス「野ネズミ」」を作成、arrayB[0]に代入
    1. ClassA型のインスタンス「野ネズミ」を作成する
    2. String型の引数「"野ネズミ"」をインスタンス変数「name」に参照させる
    3. ClassA型のクラス変数「last」に自身のインスタンス「野ネズミ」を参照させる
    4. 作成したインスタンス「野ネズミ」を引数「friend」としてClassBの引数が2つあるコンストラクタを呼び出す
    5. ClassAのコンストラクタを呼び出し、String型の引数「"プロプシー"」をインスタンス変数「name」に参照させる
    6. ClassA型のクラス変数「last」に自身のインスタンス「プロプシー」を参照させる
    7. ClassBのクラス変数「friend」にインスタンス「野ネズミ」を参照させる
  18. ClassB型のインスタンス「モプシー,ClassA型のインスタンス「ナトキン」」を作成、arrayB[0]に代入
    1. ClassA型のインスタンス「ナトキン」を作成する
    2. String型の引数「"ナトキン"」をインスタンス変数「name」に参照させる
    3. ClassA型のクラス変数「last」に自身のインスタンス「ナトキン」を参照させる
    4. 作成したインスタンス「ナトキン」を引数「friend」としてClassBの引数が2つあるコンストラクタを呼び出す
    5. ClassAのコンストラクタを呼び出し、String型の引数「"モプシー"」をインスタンス変数「name」に参照させる
    6. ClassA型のクラス変数「last」に自身のインスタンス「モプシー」を参照させる
    7. ClassBのクラス変数「friend」にインスタンス「ナトキン」を参照させる
  19. ClassB型のインスタンス「カトンテール,変数「c」」を作成、arrayB[0]に代入
    1. 変数「c」が参照するインスタンス「犬2」を引数「friend」としてClassBの引数が2つあるコンストラクタを呼び出す
    2. ClassAのコンストラクタを呼び出し、String型の引数「"カトンテール"」をインスタンス変数「name」に参照させる
    3. ClassA型のクラス変数「last」に自身のインスタンス「カトンテール」を参照させる
    4. ClassBのクラス変数「friend」にインスタンス「犬2」を参照させる
  20. ClassB型のインスタンス「ピーター,ClassA型のインスタンス「ベンジャミン」」を作成、arrayB[0]に代入
    1. ClassA型のインスタンス「ベンジャミン」を作成する
    2. String型の引数「"ベンジャミン"」をインスタンス変数「name」に参照させる
    3. ClassA型のクラス変数「last」に自身のインスタンス「野ネズミ」を参照させる
    4. 作成したインスタンス「ベンジャミン」を引数「friend」としてClassBの引数が2つあるコンストラクタを呼び出す
    5. ClassAのコンストラクタを呼び出し、String型の引数「"ピーター"」をインスタンス変数「name」に参照させる
    6. ClassA型のクラス変数「last」に自身のインスタンス「ピーター」を参照させる
    7. ClassBのクラス変数「friend」にインスタンス「ベンジャミン」を参照させる
  21. 配列「arrayA」の参照を消去、これによりインスタンス「犬3」はガーベッジとなる
  22. arrayB[0]の変数「friend」の参照を消去、それによりインスタンス「野ネズミ」はガーベッジとなる
  23. arrayB[1]の参照を消去、それによりインスタンス「モプシー」「ナトキン」はガーベッジとなる
  24. arrayB[2]の参照を消去、それによりインスタンス「カトンテール」はガーベッジとなる
  25. ClassB型のインスタンス「ルーシー,ClassA型のインスタンス「ティギー」」を作成、ClassB型の変数eへ代入
  26. 変数eの参照を消去

…何かとてつもなく無駄なことまで書いてる気がしないでもないけど、気にしないことにした。
問題を解く分には作成されるインスタンスのことだけ追いかければいいだろうに…
っていうツッコミが入るかなと予想。