web-dev-qa-db-fra.com

Java: getInstance vs Static

Quel est le but de getInstance() en Java? 

Pendant mes recherches, je continue à lire que getInstance() aide à obtenir un modèle de conception Singleton (ce qui ne représente qu'un cas sur l'ensemble du programme, à ma connaissance). Mais ne puis-je pas simplement utiliser de la statique? N'est-ce pas le but de la statique?

Si je n'avais que des méthodes et des champs statiques, en quoi cela diffère-t-il de l'utilisation de getInstance()? Existe-t-il une "portée" de statique? Par exemple, une instance par méthode ou classe?

Et s’ils sont différents, dans quels cas choisirais-je getInstance() plutôt que static?

Je m'excuse si la question n'est pas claire, je suis sûr qu'il me manque quelque chose à ce sujet, je ne peux tout simplement pas trouver quoi.

Merci pour tout conseil.

25
FreakyDan

Static ne vous donnera pas un singleton. Puisqu'il n'y a aucun moyen de transformer une classe de niveau supérieur en un singleton en Java, vous disposez de méthodes getInstance qui implémentent une logique afin de vous assurer qu'il n'y a qu'une seule instance d'une classe.

public class Singleton {

   private static Singleton singleton;

   private Singleton(){ }

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

}

Découvrez cette réponse: Classes statiques en Java

Le code ci-dessus ne permet de créer qu'une seule instance, et c'est propre, mais à partir de Java 1.6, il est préférable de créer un singleton en tant que tel, car il est légèrement plus élégant à mon humble avis:

public enum MyEnumSingleton {
    INSTANCE;

    // other useful methods here
} 

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

15
Zac Lozano

Singleton

Un singleton vous permet d'utiliser une seule référence à un objet Java. Par exemple, voici un singleton qui contient un nombre;

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

Nous allons maintenant définir la valeur de ce nombre dans la classe A:

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

Ensuite, vous pouvez accéder à cette valeur depuis une autre classe:

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

Dans cette classe, la variable number aura la valeur 42. C'est l'avantage d'un singleton par rapport à un objet simple:

Toutes les valeurs stockées dans le singleton seront accessibles à partir de "partout".


Classe statique

Le but est différent, l'avantage est d'utiliser un objet sans avoir à le créer.

Par exemple:

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

Vous pouvez maintenant utiliser la méthode sayHello () à partir de n'importe quelle classe en appelant:

MyStaticClass.sayHello(); 
8
G.T.

La méthode exacte d'implémentation d'un singleton, par exemple en utilisant une méthode de fabrique appelée getInstance(), n'est pas pertinente pour la question, qui est "méthodes statiques vs singleton avec méthodes d'instance".

Les classes sont elles-mêmes des singletons, elles se ressemblent donc de ce point de vue.

La principale différence est que les méthodes statiques ne font pas partie de la hiérarchie des classes - elles ne sont pas héritées, ce qui signifie que l'option de méthode statique vous verrouille à jamais pour utiliser cette classe exacte. d'une interface ou d'une super classe.

Les instances cependant n'ont pas ce problème, vous pouvez donc coder par exemple:

class MySingleton implements SomeInterface {
    ...
}

SomeInterface instance = MySingleton.getInstance();
3
Bohemian

Je préfère aussi utiliser static, mais parfois getInstance() est utile pour avoir certaines fonctions liées à l'objet, dans lesquelles vous pouvez modifier des variables. Si vous créez simplement des fonctions util qui ne nécessitent pas d'instance d'objet, utilisez static.

Lorsque vous utilisez les bibliothèques de quelqu'un, vous ne savez jamais si un corps de fonction a besoin d'une instance de classe. C'est pourquoi beaucoup de classes de bibliothèques utilisent getInstance().

1
Victor2748

Au lieu de vérifier null, j'aime un peu mieux cela.

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

Appelé avec ...

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

Code complet à partir de: http://www.tutorialspoint.com/design_pattern/singleton_pattern.htm

0
Jason

Une raison ignorée d'utiliser un singleton à la place de variables de membre de classe statiques est que les variables de membre statique PEUVENT utiliser l'espace et le temps du collecteur de mémoire, même dans l'éventualité où la classe n'est jamais instanciée. Considérez combien de classes sont disponibles dans rt.jar et quelle fraction d'entre elles vous utilisez probablement dans une application donnée. Notez également que l'utilisation de getInstance garantit que votre "constructeur" a été exécuté avant l'accès à l'une des variables membres. Je considère presque universellement que getInstance est synchronisé, mais j'estime que c'est une mauvaise idée. Si quelqu'un ajoute jamais une méthode de blocage synchronisée, les appels à Singleton.getInstance (). Unsynchronized () pourraient être inutilement retardés.

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