「覚え間違い」を教えてください!

Javaを学習するようになり1つ疑問がわきましたので、
質問させてください。

Point p = new Point(100,300); …①
Point q = new Point(200,400); …②

q=p; …③

としたとき、qは①で作成したインスタンスを
参照するようになると理解したのですが、
理解が正しい場合②で作成したインスタンスは
どうなってしまうのでしょうか。
そのインスタンスは再度紐付けることはできないでしょうか。

A 回答 (3件)

オブジェクトが生成されると、ヒープというメモリ領域にオブジェクトの情報が書き加えられます このオブジェクト情報はどこからも参照されなくなっても残りますが、ガーベッジコレクタと言う機能が動作するとどこからも参照されなくなって不要になったオブジェクト情報はメモリ上から削除されます



オブジェクト内にはfinalizeメソッドと言うメソッドをオーバーライドして入れる事ができます このメソッドを入れておくとメモリ上からそのオブジェクトの情報が削除される直前に削除されるオブジェクト情報内でそのメソッドを動かす事ができます

どこにも参照を残さずに再度オブジェクト情報を回収して使用するプログラムの例を下に示しました
ガーベッジコレクタが動作するまでプログラムを動かして恣意的に参照されなくなったオブジェクト情報を削除させ、結果fnalizeメソッドを動かしてfinalizeメソッド内でインスタンス化したオブジェクトIのstatic Pointの変数Poitsave内に削除される非参照のオブジェクト情報をコピーして回収しています
その後、その情報をクラスIのmainメソッド内のPoint変数qに再度代入する事で変数qの内容を元に戻しています

ガーベッジコレクタが動くまで待たねばならないので時間はかかるかも知れませんがこれで何もかも元通りになります 複数の非参照にされたオブジェクトを元に戻したい場合はfinalizeメソッド等にこれ以外の工夫が必要でしょうが、工夫次第では可能になると思います。

public class I{


static Point Pointsave;


public static void main(String[] args){

int flag=0;


Point p = new Point(100,300);// …①
Point q = new Point(200,400);// …②


q=p;// …③

System.out.println("q:"+q.c+","+q.d);// …④


Runtime rt = Runtime.getRuntime();
rt.gc();



while(flag==0){

try{

System.out.println("ガーベジコレクタが動作し、finalizeメソッドが動作したため②で一度非参照にされたオブジェクトの再度回収が可能になった");
System.out.println("Pointsave内情報:"+Pointsave.c+","+Pointsave.d);
flag=1;

}catch(Exception e){
System.out.println("オブジェクトが未開放です");
}


}

q=Pointsave;

System.out.println("q:"+q.c+","+q.d);// …⑤
}
}



class Point{

Point(int a,int b){
c=a;
d=b;
}

protected void finalize()throws Throwable{

Point Newpoint=new Point(c,d);
I NewI=new I();

NewI.Pointsave=Newpoint;
}

int c=0;
int d=0;
}
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
サンプルまで記載していただき本当にありがとうございます。
まだ学習が追いついていない箇所がありますので、
もう少し進んでからサンプルを確認させて頂きます。

お礼日時:2016/11/09 11:43

>②で作成したインスタンスはどうなってしまうのでしょうか。


暫くすると消えます。

>そのインスタンスは再度紐付けることはできないでしょうか。
どこかに参照を残しておくだけの話ですから、難しくはありません。

どこにも参照を残さずに再度紐づけはできません。
そもそもそんなことの用途がないです。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます!

お礼日時:2016/11/09 11:42

q=p; …③


以前に②で作成したインスタンスを
Point a=q;
のようにどこかの変数で参照して参照した変数ががまだ残っていれば
そこから参照し続けられますが
それがなければ③の時点で②で作成したインスタンスはどこからも参照されなくなりガーベッジコレクション(消去)の対象になりガーベッジコレクションを待つ状態になります。この時点からいくらか時間がたってからオブジェクトは消去されます。
オブジェクトにfinalize()メソッドをオーバーライドしておくとオブジェクトがガーベッジコレクションを受ける直前にfinalize()メソッドが自動的に呼び出されるのでfinalize()メソッドの中にオブジェクトへの参照を別の変数に渡す動作を入れるとインスタンスを再度参照するようにできるようです
finalize()メソッドは使わない方がいい事で有名らしいですが、そのような方法も取れるようです。

参考
http://www.booran.com/menu/java/garbagecollectio …
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。

まだ初心者のため後半部分が少し難しかったのですが、
もう少し勉強していき、理解を深めたいと思います。

本当にありがとうございました。

お礼日時:2016/10/27 10:12

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


おすすめ情報