2009-11-17 4 views

Répondre

34

Ils exposent différentes interfaces et contrat pour la méthode.

La première déclaration doit renvoyer une collection dont le type d'éléments est le même que celui de la classe d'argument. Le compilateur déduit le type de N (si non spécifié). Ainsi, les deux déclarations suivantes sont valables lors de l'utilisation de la première déclaration:

Collection<Integer> c1 = getThatCollection(Integer.class); 
Collection<Double> c2 = getThatCollection(Double.class); 

La deuxième déclaration ne déclare pas la relation entre l'argument de type collection retournée à la classe d'arguments. Le compilateur suppose qu'ils ne sont pas liés, de sorte que le client devrait utiliser le type retourné comme Collection<? extends Number>, peu importe ce que l'argument est:

// Invalid statements 
Collection<Integer> c1 = getThatCollection(Integer.class); // invalid 
Collection<Double> c2 = getThatCollection(Double.class); // invalid 
Collection<Number> cN = getThatCollection(Number.class); // invalid 

// Valid statements 
Collection<? extends Number> c3 = getThatCollection(Integer.class); // valid 
Collection<? extends Number> c4 = getThatCollection(Double.class); // valid 
Collection<? extends Number> cNC = getThatCollection(Number.class); // valid 

Recommandation

En effet, s'il existe une relation entre la tapez entre l'argument de type renvoyé et l'argument passé, il est préférable d'utiliser la première déclaration. Le code client est plus propre comme indiqué ci-dessus.

Si la relation n'existe pas, il vaut mieux éviter la deuxième déclaration. Avoir un type renvoyé avec un caractère générique délimité oblige le client à utiliser des caractères génériques partout, de sorte que le code client devient claqué et illisible. Joshua Bloch montre que vous devriez Avoid Bounded Wildcards in Return Types (diapositive 23). Alors que les caractères génériques liés dans les types de retour peuvent être utiles dans certains cas, la laideur du code de résultat devrait, à mon humble avis, outrepasser le bénéfice.

+3

+1 pour une explication claire des différences. Grignotage mineur - Je pense que vous allez trop loin en supposant que le premier est toujours le meilleur choix - je dirais "inutile de dire" le meilleur choix dépendrait du contexte. –

+0

@Steve Merci! J'ai ajouté une explication pourquoi la deuxième déclaration doit être évitée. – notnoop

+0

+1 Super réponse! – Stephan

-3

Dans ce cas particulier, non. Cependant, la seconde option est plus flexible car elle vous permet de renvoyer une collection qui contient des éléments d'un type différent (même s'il s'agit aussi d'un nombre) que le type contenu par le paramètre collection.

Exemple concret:

Collection<? extends Number> getRoot(Class<? extends Number> number){ 
    ArrayList<Integer> result=new ArrayList<Integer>(); 
    result.add(java.util.Math.round(number); 
    return result) 
} 
Questions connexes