4
class A
{
    B b;
    public A()
    {
        b = new B(this);
        //initialization of class A variables
    }

    public void meth1()
    {

    }
}

class B
{
    A a;
    public B(A a)
    {
        this.a = a;
    }
}

この参照をこのように渡すべきではないことは知っていますが、これを行うとどうなりますか

他のいくつかのクラスは、クラスAコンストラクターを呼び出します。「この」参照が実際にメモリを割り当てたのはいつですか。super()が呼び出される前に、Aのコンストラクターが呼び出されるとすぐに、メモリが割り当てられますか。

クラスBがスレッドであり、BにはAの参照があるため、「この」参照にまだメモリが割り当てられていない場合、Aのコンストラクタが返されない前にBがAのメソッドを呼び出すことができるとします。

4

5 に答える 5

3

オブジェクトのメモリは、コンストラクターが実行される前に割り当てられます。そうしないと、コンストラクターは変数の値を書き込む場所がありません。

したがって、現在のオブジェクト(別名)への参照をコンストラクター内の他のコードに渡すことができます。this

お気づきのように、その時点ではオブジェクトは完全には構築されておらず、実際にそれを行うのは悪い考えですが、オブジェクトのが一貫性のない状態になる可能性があるため、「ただ」です。この時点で、メモリはすでにそのオブジェクトに割り当てられ、予約されています。

thisこれは「現在のオブジェクト」への単なる参照であり、非静的メソッドが取得する単なる別のパラメーターと考えることができます。実際、それが実際にJVMがそれを処理する方法です。JVMS§2.6.1ローカル変数を参照してください。

インスタンスメソッドの呼び出しでは、ローカル変数0を常に使用して、インスタンスメソッドが呼び出されているオブジェクトへの参照を渡します(thisJavaプログラミング言語)。

したがって、「いつ割り当てられるか」に対する直接の答えthisは、事実上次のとおりです。オブジェクトでメソッドを呼び出すときはいつでも。

于 2013-03-21T16:03:27.000 に答える
1

これは現在のオブジェクトを参照し、すべてのオブジェクトには「新規」を使用してメモリが割り当てられます

于 2013-03-21T16:21:02.240 に答える
0

JVMがnew命令を処理しているときにメモリが割り当てられます。たとえば、コードが次のようになっている場合:

A a = new A();
      ^
      here the memory for A is allocated

thisに渡すのは確かに問題になる可能性がありますB。のコンストラクターは、のコンストラクターが終了する前にのBインスタンスメソッドを呼び出すことができます。起こりうる問題を回避するために、のコンストラクタの最後に行を移動する必要があります。または、セッターを使用して外部からオブジェクトのライフサイクルを管理することもできます。AAA

于 2013-03-21T16:05:40.190 に答える
0

thisコンストラクターが呼び出される前に割り当てられます。実際、super()電話は必要ありません。親クラスの作成が確実に行われるようにするだけで、親クラスがであるかどうかは関係ありませんObject。また、Aのメソッドは、オブジェクトが作成されるとすぐに(コンストラクターが呼び出される前でも)使用できるため、BがコンストラクターでAへの参照を取得した場合、コンストラクターでA自体と同じようにAのメソッドを使用できます。Aが完全に初期化されていないときに使用できるように、必ずAのメソッドを作成するか、初期化の完了後にBを作成して開始してください。

于 2013-03-21T16:05:58.933 に答える
0

Aメソッドを変更または呼び出さない限り、Aまたはそのコンストラクターのメンバーが機能しBます。(他の回答を参照してください)

完全に初期化されていないオブジェクト(構築後)でメソッドを呼び出すと、何が起こるかが定義されません。特に複数のスレッドを使用する場合(メモリバリアを参照)。

このトピックの詳細: コンストラクターをチェーンするときに、JVMの暗黙のメモリバリアはどのように動作しますか?

于 2013-03-21T16:14:46.233 に答える