Подтвердить что ты не робот

Java: getInstance vs Static

Какова цель getInstance() в Java?

Во время моего исследования я продолжаю читать, что getInstance() помогает достичь шаблона проектирования Singleton (что означает только один экземпляр всей программы для моего понимания). Но не могу ли я использовать статику? Разве это не та точка статического?

Если бы у меня были только статические методы и поля, как бы это отличалось от использования getInstance()? Есть ли "сфера" статичности? Например, один экземпляр для метода или класса?

И если они разные, в каких случаях я бы выбрал getInstance() с помощью static?

Извиняюсь, если вопрос неясен, я уверен, что у меня что-то не хватает по этому вопросу, я просто не могу понять, что.

Спасибо за любой совет.

4b9b3361

Ответ 1

Статика не даст вам синглтон. Поскольку нет способа сделать класс верхнего уровня одиночным в Java, у вас есть методы getInstance, которые реализуют некоторую логику, чтобы быть уверенным, что есть только один экземпляр класса.

public class Singleton {

   private static Singleton singleton;

   private Singleton(){ }

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

}

Посмотрите этот главный ответ: Статические классы в Java

Вышеприведенный код позволит создать только один экземпляр, но он чист, однако с Java 1.6 лучше создать singleton как таковой, поскольку он немного более изящный IMHO:

public enum MyEnumSingleton {
    INSTANCE;

    // other useful methods here
} 

Источник: http://www.vogella.com/tutorials/DesignPatternSingleton/article.html

Ответ 2

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

Ответ 3

Точный метод реализации singleton, например, с помощью метода factory, называемый getInstance(), не имеет отношения к вопросу, который представляет собой "статические методы vs singleton с методами экземпляра".

Классы сами по себе являются эффективными синглонами, поэтому из этого аспекта они похожи.

Основное отличие состоит в том, что статические методы не являются частью иерархии классов - они не наследуются, что означает, что параметр статического метода навсегда блокирует вас на использовании этого точного класса, и на него нельзя ссылаться каким-либо другим способом являясь реализацией некоторого интерфейса или суперкласса.

У экземпляров, однако, нет этой проблемы, поэтому вы можете использовать код, например:

class MySingleton implements SomeInterface {
    ...
}

SomeInterface instance = MySingleton.getInstance();

Ответ 4

Я предпочитаю использовать static тоже, но иногда getInstance() полезно иметь некоторые функции, которые будут связаны с объектом, в котором вы можете изменять переменные. если вы просто выполняете некоторые функции утилиты, которым не нужен экземпляр объекта, используйте static.

Когда вы используете какие-то библиотеки, вы никогда не знаете, нуждается ли тело элемента в экземпляре класса. Поэтому многие классы библиотеки используют getInstance().

Ответ 5

Вместо того, чтобы проверять значение 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

Ответ 6

Одна из упущенных причин использовать одноэлемент вместо статических переменных-членов класса состоит в том, что статические переменные-члены могут использовать пространство и время сбора мусора даже в том случае, если класс никогда не создается. Подумайте, сколько классов доступно вам в rt.jar и какая небольшая часть из них вы, вероятно, используете в любом конкретном приложении. Также подумайте, что использование getInstance гарантирует, что ваш "конструктор" будет запущен до того, как будет получен доступ к любой из переменных-членов. Я почти повсеместно вижу 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() );
}