web-dev-qa-db-fra.com

Pourquoi pas de constructeur public pour Optional en java?

Pourquoi Optional a-t-il des méthodes comme of() et ofNullable() au lieu d'un constructeur public?

30
Gopal S Akshintala

Extrait de Joshua Bloch effective Java, Chapitre 2. Création et destruction d'objets, 1 élément:

Considérez les méthodes fabriques statiques au lieu des constructeurs

Pourquoi?

L'un des avantages des méthodes fabriques statiques est que, contrairement aux constructeurs, ils ont des noms.

Avec les méthodes fabriques statiques, nous pouvons spécifier un comportement d'instanciation dans la définition de la méthode. Cela facilite l'utilisation de l'API et empêche les clients d'appeler des constructeurs incorrects.

Par exemple ici: Dans Optional.ofNullable -> nous autorisons la valeur null pour instancier le facultatif , dans Optional.of La valeur null n'est pas autorisée et une exception est levée. Nous ne pourrions pas utiliser le constructeur ici.

private Optional(T value) {
    this.value = Objects.requireNonNull(value); //this throws NullPointerException
}
public static <T> Optional<T> of(T value) {
        return new Optional<>(value);
}
public static <T> Optional<T> ofNullable(T value) {
        return value == null ? empty() : of(value);
} 

Un autre avantage (déjà mentionné):

Un autre avantage des méthodes de fabrique statique est que, contrairement aux constructeurs, ils ne sont pas obligés de créer un nouvel objet chaque fois qu’ils sont appelés.

Dans Facultatif, la valeur vide est instanciée une seule fois, puis stockée dans le champ statique. Cette valeur est toujours réutilisée lorsque le programme a besoin d'une valeur vide.

private static final Optional<?> EMPTY = new Optional<>(); //instantiate value when program starts

public static<T> Optional<T> empty() {
    @SuppressWarnings("unchecked")
    Optional<T> t = (Optional<T>) EMPTY; //return stored value when requested
    return t;
}
37
Stefan Repcek

La raison est en fait assez simple: un optionnel vide est une constante statique pour optimiser la mémoire. Si un constructeur était utilisé, il devrait créer une nouvelle instance à chaque fois pour un cas commun.

public static<T> Optional<T> empty() {
    @SuppressWarnings("unchecked")
    Optional<T> t = (Optional<T>) EMPTY;
    return t;
}

public static <T> Optional<T> ofNullable(T value) {
    return value == null ? empty() : of(value);
}
21
Minn

Facultatif est un classe basée sur la valeur sans aucun constructeur

n'ont pas de constructeurs accessibles, mais sont plutôt instanciés via des méthodes fabriques qui ne font aucun engagement quant à l'identité des instances renvoyées

10
user7294900

Parce que les méthodes d'usine doivent être préférées aux constructeurs publics lorsque les cas d'instanciation possibles sont connus.
Cela facilite l’utilisation de l’API pour les classes clientes.
En outre, les méthodes d'usine permettent de décider si une instance doit être créée à chaque invocation.
Dans le cas de Optional.empty() , il est logique de mettre en cache la valeur car celle-ci est immuable.

9
davidxxx