简体   繁体   中英

Java: getInstance vs Static

What is the purpose of getInstance() in Java?

During my research I keep reading that getInstance() helps achieve a Singleton design pattern (which means just one instance across the whole program to my understanding). But can't I just use static? Isn't that the whole point of static?

If I were to just have static methods and fields, how would it differ from using getInstance() ? Is there a "scope" of static? For example, one instance per method or class?

And if they are different, in what cases would I choose getInstance() over using static?

I apologize if the question is unclear, I am sure I am missing something on the subject matter, I just can't figure out what.

Thank you for any and all advice.

Static will not give you a singleton. Since there is no way of making a top-level class a singleton in Java, you have getInstance methods which will implement some logic to to be sure there is only one instance of a class.

public class Singleton {

   private static Singleton singleton;

   private Singleton(){ }

   public static synchronized Singleton getInstance( ) {
      if (singleton == null)
          singleton=new Singleton();
      return singleton;
   }

}

Check out this top answer: Static Classes In Java

The above code will allow only one instance to be created, and it's clean, however as of Java 1.6, it is better to create singleton's as such since it is slightly more elegant IMHO:

public enum MyEnumSingleton {
    INSTANCE;

    // other useful methods here
} 

Source: http://www.vogella.com/tutorials/DesignPatternSingleton/article.html

Singleton

A singleton allows you to use a single reference to a java Object. For example, here is a singleton which contains a number;

public class MySingleton {

    private int myNumber;
    private static MySingleton instance;

    public static MySingleton getInstance() {
        if (instance == null) {
             instance = new MySingleton();
        }
        return instance;
    }

    private MySingleton() {}

    public void setMyNumber(int myNumber) {
        this.myNumber = myNumber;
    }

    public int getMyNumber() {
       return myNumber;
    }
}

Now we are going to set the value of this number in the A class:

public class A {
    /*...*/
    MySingleton mySingleton = MySingleton.getInstance();
    mySingleton.setMyNumber(42);
    /*...*/
}

Then, you can access this value from another class:

public class B {
    /*...*/
    MySingleton mySingleton = MySingleton.getInstance();
    int number = mySingleton.getMyNumber();
    /*...*/
}

In this class the number variable will have the value 42. This is the advantage of a singleton over a simple object:

All the values stored in the singleton will be accessible from "everywhere".


Static class

The purpose is different, here the advantage is to use an object without having to create it.

For example:

public static class MyStaticClass {
    public static void sayHello() {
        System.out.println("Hello");
    }
}

Now you can use the sayHello() method from any classes by calling:

MyStaticClass.sayHello(); 

The exact method of implementing a singleton, for example using a factory method called getInstance() , isn't that relevant to the question, which is "static methods vs singleton with instance methods".

Classes are themselves effectively singletons, so from that aspect they are similar.

The main difference is that static methods are not part of class hierarchy - they are not inherited, which means the static method option locks you forever to using that exact class and it can't be referred to in any other way, such being an implementation of some interface or a super class.

Instances however don't have this problem, so you can code for example:

class MySingleton implements SomeInterface {
    ...
}

SomeInterface instance = MySingleton.getInstance();

I prefer to use static too, but sometimes getInstance() is helpful to have some functions that will be related to the object, in which you can modify variables. if you are simply making some util functions that do not need an instance of an object, use static .

When you are using someone's libraries, you never know if a function body needs a class instance. That's why a lot of library classes are using getInstance() .

One overlooked reason to use a singleton instead of static class member variables is that the static member variables MAY use space and garbage collector time even in the event the class is never instantiated. Consider how many classes are available to you in rt.jar and what a small fraction of them you probably use in any given application. Also consider that using getInstance ensures your "constructor" has run before any of the member variables are accessed. I almost universally see getInstance as synchronized but I feel this is a bad idea. If anyone ever adds a synchronized blocking method calls to Singleton.getInstance().unsynchronized() could be needlessly held up.

private static Singleton instance = null;
private Singleton() {}
public final static Singleton getInstance() {
    return (instance != null) ? instance : makeInstance();
}
private final static synchronized Singleton makeInstance() {
    return ( instance != null ) ? instance : ( instance = new Singleton() );
}

Instead of checking for null, I like this a little better.

public class SingleObject {

    //create an object of SingleObject
    private static SingleObject instance = new SingleObject();

    //make the constructor private so that this class cannot be
    //instantiated
    private SingleObject(){}

    //Get the only object available
    public static SingleObject getInstance(){
        return instance;
    }
}

Called with...

public class SingletonPatternDemo {
   public static void main(String[] args) {

      //illegal construct
      //Compile Time Error: The constructor SingleObject() is not visible
      //SingleObject object = new SingleObject();

      //Get the only object available
      SingleObject object = SingleObject.getInstance();
   }
}

Full code from: http://www.tutorialspoint.com/design_pattern/singleton_pattern.htm

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM