6
votes

Qu'est-ce qu'un type de retour naturel en java?

Je lis Joshua Blochs "Effective Java", et il dit

Un troisième avantage des méthodes de fabrique statiques est que, contrairement aux constructeurs, elles peuvent renvoyer un objet de n'importe quel sous-type de leur type de retour. Cela vous donne une grande flexibilité dans le choix de la classe de l'objet retourné. Une application de cette flexibilité est qu'une API peut renvoyer des objets sans rendre leurs classes publiques. Masquer les classes d'implémentation de cette manière conduit à une API très compacte. Cette technique se prête aux frameworks basés sur des interfaces, où les interfaces fournissent des types de retour naturels pour les méthodes de fabrique statiques.

Quelqu'un peut-il expliquer ce que sont les "types de retour naturel"? Merci!


1 commentaires

Je ne pense pas que cela signifie quelque chose de spécifique aux fonctionnalités java, à la syntaxe ou aux types de données. Il ne s'agit pas du tout de java, mais d'interfaces. Le synonyme est probablement "commun", "plus intuitif" ...


3 Réponses :


3
votes

Dans ce contexte, "naturel" signifie simplement naturel pour le contexte de la méthode de fabrique; c'est-à-dire ce qui est approprié ou ce à quoi vous vous attendez. Intuitif serait un autre synonyme.

Ceci est juste un usage normal de l'anglais ... pas une terminologie spécifique à l'informatique ou à Java.


0 commentaires

1
votes

Je pense qu'il fait référence à la classe de la fabrique (qui est généralement une méthode statique dans la classe) qui n'a pas besoin d'instancier cette classe spécifique. Cependant, je ne pense pas que ce soit un terme défini ou généralement utilisé.

Exemple: Terme

public abstract class Term {

    public abstract Integer evaluate();

    static Term literal(Integer number) {
        return new Literal(number);
    }

    static Term add(Term left, Term right) {
        return new Addition(left, right);
    }

    private static class Addition extends Term {
        private Term left;
        private Term right;

        public Addition(Term left, Term right) {
            this.left = left;
            this.right = right;
        }

        @java.lang.Override
        public Integer evaluate() {
            return left + right;
        }
    }

    private static class Literal extends Term {
        private Integer number;

        public Literal(Integer number) {
            this.number = number;
        }

        @java.lang.Override
        public Integer evaluate() {
            return number;
        }
    }
}

Il s'agit d'une classe appelée Term avec 2 méthodes d'usine: literal et add , qui renvoient toutes deux un Term mais une sous-classe de celui-ci. Le terme lui-même n'est pas instantable, car il est abstrait. Pour le monde extérieur, les classes internes ne sont pas visibles (elles sont privées). Accessible est juste l'interface / classe abstraite Term , qui est ce qui est référencé dans

Une application de cette flexibilité est qu'une API peut renvoyer des objets sans rendre leurs classes publiques.

Je pense que la "classe naturelle" à renvoyer ici serait un Term et new est tenu de retourner une instance exactement du type donné. Une méthode de fabrique peut renvoyer des sous-types.

Exemple: Guava

Guava est une bibliothèque qui fournit des classes de collection supplémentaires pour Java. L'une d'elles est une liste immuable. Il contient plusieurs méthodes d'usine pour des cas spécifiques, par exemple une pour une liste vide et une autre pour répertorie exactement lequel .

Je ne pense pas que le terme "classe naturelle" soit "officiel". Sans le contexte (et même avec lui, comme on peut le voir ici) il n'est pas sûr qu'il soit reconnu. J'ai donc pris votre question à une échelle plus large et expliqué le sujet du chapitre.


4 commentaires

"Je ne pense pas que le terme" classe naturelle "soit" officiel "." - précisément! Au cours de mes 20 ans et plus de programmation Java / lecture de spécifications, etc., je ne me souviens pas avoir jamais vu l'expression «classe naturelle» utilisée comme terminologie. C'est pourquoi je pense que Bloch utilise simplement "naturel" comme mot anglais normal. Comme on le ferait ... naturellement.


La question concernant les réponses aux questions est la suivante: que lisez-vous de la question et que répondez-vous. Si vous prenez la question au pied de la lettre: il n'y a pas de «classe naturelle» au meilleur de ma / notre connaissance. Cependant, le chapitre du livre a un sens. J'ai décidé de répondre à cela, au lieu de la question littérale. Être capable de formuler correctement une question fait souvent déjà partie de la réponse :)


La première phrase dit - "Je ne suis pas d'accord sur le fait que ce soit" juste de la langue anglaise ". Je le réfute. Comme il ne s'agit pas d'une terminologie reconnue (officielle ou autre), il ne doit s'agir que de l'anglais. De toute évidence, l'auteur a un sens à l'esprit lorsqu'il utilise ces mots ... mais il n'essaie pas d'utiliser ou d'inventer de la terminologie ici. Mais votre réponse est disant que cette est terminologie. . sans aucune preuve à l'appui. (Votre preuve supposée est en fait une argumentation, et 100% compatible avec l'utilisation / le sens anglais normal du mot "naturel".)


J'ai reformulé cette phrase. Je pense toujours qu'il se réfère à la classe spécifique de la méthode de l'usine statique. Je comprends cependant votre point. Je ne suis pas en désaccord sur le fait que le terme soit défini (je ne pense pas non plus). J'ai interprété «juste anglais» dans le sens où il ne fait pas référence à un terme de programmation, ce que je pense que c'est le cas.



2
votes

Un exemple concret de cela serait quelque chose comme les méthodes d'usine ImmutableList de Guava.

Cela a 13 surcharges de la méthode of , avec un nombre croissant de paramètres. Si vous regardez la source des 3 premiers :

@SuppressWarnings("unchecked")
public static <E> ImmutableList<E> of() {
  return (ImmutableList<E>) EMPTY;
}

public static <E> ImmutableList<E> of(E element) {
  return new SingletonImmutableList<E>(element);
}

public static <E> ImmutableList<E> of(E e1, E e2) {
  return construct(e1, e2);
}

Les méthodes zero-arg et two-arg renvoient en fait une instance de RegularImmutableList , qui est une sous-classe de ImmutableList ; la méthode one-arg renvoie une instance de SingletonImmutableList.

Mais ce détail de la sous-classe est-il pertinent pour vous, l'appelant? Non. Il est "naturel" que si vous appelez une méthode qui construit une ImmutableList , vous récupériez une référence à une ImmutableList.

"Naturel "dans ce sens signifie peut-être" à un niveau d'abstraction approprié ".


0 commentaires