5

最近、別のクラスからクラスの一意のインスタンスを取得することについて質問しました。

( Java で別のクラスからクラスの特定のインスタンスを取得する方法は? )

だから、私はそれを機能させようとしています:

私のApplication

public class Application
{

    // I will always have only one instance of Application

    private static Application _application;

    // Every instance of Application (one in my case) should have its own View

    private View view;

    // Constructor for new instance of Application

    private Application()
    {
        view = new View();
    }

    // Getter for my unique instance of Application

    public static Application getSharedApplication()
    {
        if (_application == null)
            _application = new Application();
        return _application;
    }

    // Main class

    public static void main(String[] args)
    {
        // So I'm accessing my instance of Application
        Application application1 = getSharedApplication();

        // Here is object reference
        System.out.println(application1);

        // And now I'm accessing the same instance of Application through instance of View
        Application application2 = application1.view.getApplication();

        // Here is object reference
        System.out.println(application2);
    }

}

私のView

public class View
{

    // I'm accessing my instance of Application again

    public static Application application = Application.getSharedApplication();

    // This method should return my unique instance of Application

    public Application getApplication()
    {
        return application;
    }

}

問題は、mainメソッドが異なるオブジェクト参照を返すことです。

Application@1430b5c
Application@c2a132

コードの何が問題になっていますか?

4

4 に答える 4

7

何が起こるかは次のとおりです。

  • プログラムが最初に呼び出すApplication application1 = getSharedApplication();
  • それは次に呼び出す静的メソッドを呼び出しますnew Application()-その呼び出しは、のメンバーであるViewクラスをロードする必要がありApplicationます。
  • View クラスがロードされ、その静的メンバーが初期化されて実行されます (この段階ではまだ nullgetSharedApplication();であることに注意してください)。_applicationそれはnew Application()あまりにも作成します

これで、2 つの Application インスタンスができました。

View v = new View();メインの最初の行として追加する場合、Application のインスタンスは 1 つしかないことに注意してください(View の静的変数から 1 回読み込まれます)。よく考えてみれば当然のことですが、あまり直感的ではありません...

于 2012-08-16T18:05:09.417 に答える
4

このような質問に対する一般的な答えは、次のとおりです。デバッガを使用してください。たとえば、 のコンストラクターにブレーク ポイントを設定し、Applicationプログラムを実行して、コンストラクターが 2 回目に実行されたときにスタックを調べることができます。

これを行うと、次のようなことに注意してください。

Application.<init>() line: 21   
Application.getSharedApplication() line: 31 
View.<clinit>() line: 59    
Application.<init>() line: 23   
Application.getSharedApplication() line: 31 

つまり、ビューは、共有アプリケーションが完全に構築される前 (および共有アプリケーションが static フィールドに格納される前) に共有アプリケーションを取得しようとします。

于 2012-08-16T18:03:15.843 に答える
1

ビューの初期化を以下のように変更した場合

public static Application getSharedApplication() {

    if(_application == null)
    {
        _application = new Application();
        view = new View();
    }

作成されているインスタンスは1つだけです。理由は、アプリケーションが完全に初期化される前にViewインスタンスを作成しているためです。クラスが初めて要求されたときに静的変数がロードされるため、この動作が発生しています。

とにかく私はこれを決してしないことを学びました:)ありがとう:)

于 2012-08-16T18:31:51.910 に答える
0

getSharedApplication() メソッドは、synchronized キーワードを使用する必要があります。そうしないと、2 つのスレッドが最初の if ステートメント ブロックに入り、両方が異なる変数を作成する可能性があります。

それがここで起こっていることかどうかはわかりません。実際に何が起こっているかを追跡できるように、どこにでも debug/print ステートメントを追加してみてください。

于 2012-08-16T18:06:16.120 に答える