5

I have asked about getting unique instance of class from another class recently.

( How to get specific instance of class from another class in Java? )

So, I am trying to make it work:

My 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);
    }

}

My 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;
    }

}

The problem is that main method returns different object references.

Application@1430b5c
Application@c2a132

What's wrong with my code?

Community
  • 1
  • 1
Edward Ruchevits
  • 6,411
  • 12
  • 51
  • 86

4 Answers4

7

Here is what happens:

  • the program first calls Application application1 = getSharedApplication();
  • that in turn calls the static method which calls new Application() - that call needs to load the View class, which is a member of Application.
  • the View class is loaded and its static member is initialised and runs getSharedApplication(); (note that at this stage, _application is still null). That creates a new Application() too

You now have 2 Application instances.

Note that if you add View v = new View(); as the first line of your main, you only have one instance of Application (which gets loaded once from the static variable of View). That makes sense when you think hard about it but is not very intuitive...

assylias
  • 321,522
  • 82
  • 660
  • 783
4

The general answer to such questions is: Use a debugger! For instance, you might set a break point in the constructor of Application, run your program, and inspect the stack when the constructor executes for the second time.

If you do this, you'll note something like this:

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

That is, the view wants to get the shared application before the shared application has been fully constructed (and before the latter is stored in the static field).

meriton
  • 68,356
  • 14
  • 108
  • 175
1

If you change initialization of View like below

public static Application getSharedApplication() {

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

You will find only one instance is getting created. Reason is you are creating View instance before Application is completely initialized. Because static variables are loaded when class is requested for the first time so this behavior is happening.

Anyway I learnt that never do this :) thanks:)

Amit Deshpande
  • 19,001
  • 4
  • 46
  • 72
0

The getSharedApplication() method should use the synchronized keyword. Otherwise two threads may enter the first if statement block and both create different variables.

I'm not sure if that is what is happening here. Try adding debug/print statements everywhere so you can follow what is really happening.

Sarel Botha
  • 12,419
  • 7
  • 54
  • 59