Java:getInstance vs Static

时间:2014-06-13 21:39:45

标签: java design-patterns static singleton

Java中getInstance()的目的是什么?

在我的研究过程中,我继续阅读getInstance()有助于实现Singleton设计模式(这意味着整个程序中只有一个实例符合我的理解)。但我不能使用静态吗?那不是静止的全部意义吗?

如果我只有静态方法和字段,它与使用getInstance()有什么不同?是否有"范围"静电?例如,每个方法或类一个实例?

如果它们不同,我会在什么情况下选择getInstance()而不是使用静态?

如果问题不清楚,我很抱歉,我确信我遗漏了有关主题的内容,我无法弄清楚是什么。

感谢您提供任何建议。

6 个答案:

答案 0 :(得分:15)

静态不会给你一个单身人士。由于无法在Java中将顶级类设为单例,因此您可以使用getInstance方法实现某些逻辑,以确保只有一个类的实例。

public class Singleton {

   private static Singleton singleton;

   private Singleton(){ }

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

}

查看以上最佳答案:Static Classes In Java

上面的代码只允许创建一个实例,并且它很干净,但是从Java 1.6开始,最好是创建单独的实例,因为它稍微更优雅恕我直言:< / p>

public enum MyEnumSingleton {
    INSTANCE;

    // other useful methods here
} 

来源:http://www.vogella.com/tutorials/DesignPatternSingleton/article.html

答案 1 :(得分:8)

的Singleton

单例允许您使用对java对象的单个引用。例如,这是一个包含数字的单例;

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

现在我们要在A类中设置这个数字的值:

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

然后,您可以从另一个类访问此值:

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

在这个类中,number变量的值为42.这是单例相对​​于简单对象的优势:

  

可以从中访问存储在单例中的所有值   “无处不在”


静态类

目的不同,这里的优点是使用对象而不必创建它。

例如:

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

现在,您可以通过调用:

从任何类中使用sayHello()方法
MyStaticClass.sayHello(); 

答案 2 :(得分:3)

实现单例的确切方法,例如使用名为getInstance()的工厂方法,与问题无关,即“静态方法与单例和实例方法”。

类本身就是有效的单例,所以从这方面来看它们是相似的。

主要区别在于静态方法不是类层次结构的一部分 - 它们不是继承的,这意味着静态方法选项会永远锁定您使用那个确切的类,并且不能以任何其他方式引用它,例如是一些接口或超类的实现。

但实例没有此问题,因此您可以编写代码:

class MySingleton implements SomeInterface {
    ...
}

SomeInterface instance = MySingleton.getInstance();

答案 3 :(得分:1)

我也喜欢使用static,但有时getInstance()有助于拥有一些与对象相关的函数,您可以在其中修改变量。如果您只是制作一些不需要对象实例的util函数,请使用static

当您使用某人的库时,您永远不知道函数体是否需要类实例。这就是为什么很多库类都在使用getInstance()

答案 4 :(得分:0)

而不是检查null,我更喜欢这个。

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

用...打电话

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

完整代码来自:http://www.tutorialspoint.com/design_pattern/singleton_pattern.htm

答案 5 :(得分:0)

使用单例而不是静态类成员变量的一个被忽视的原因是静态成员变量可能使用空间和垃圾收集器时间,即使在类从未实例化的情况下也是如此。考虑在rt.jar中可以使用多少个类,以及在任何给定的应用程序中可能使用的它们中的一小部分。还要考虑使用getInstance确保你的&#34;构造函数&#34;在访问任何成员变量之前运行。我几乎普遍认为getInstance是同步的,但我觉得这是一个坏主意。如果有人曾经向Singleton.getInstance()添加一个同步的阻塞方法调用。可能会不必要地阻止unsynchronized()。

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