pour une interface générique: la différence entre les deux champs: p> est que Cependant, consultez les éléments suivants: P> foo2 code > est un type générique et
foo code> n'est pas. Étant donné que
? Code> est un caractère générique (que je pense que tout type) et que chaque type est un sous-type d'objet, alors je m'attends à ce que j'attends
FOO > Code> et
et
et
FOO
public class Puzzler {
void f() {
Integer i = null;
Foo<?> foo1 = null;
foo1.foo(i); // ERROR
Foo foo2 = null;
foo2.foo(i); // OKAY
Foo<Integer> foo3 = null;
foo3.foo(i); // OKAY
Foo<Object> foo4 = null;
foo4.foo(i); // OKAY
}
private interface Foo<T> {
void foo(T t);
}
}
5 Réponses :
Voici un exemple de pourquoi modifie maintenant votre exemple à ceci: p > puisque Notez que P> foo > code> est sémantiquement la même chose que
foo Extend Object> Code>: C'est un
FOO code> avec le paramètre de type de quelque chose spécifique, mais la seule chose à propos de "quelque chose" est que c'est une sous-classe de
objet code> (qui ne dit pas trop, car toutes les classes sont des sous-classes de
objet code>).
foo
foo code> avec le paramètre de type spécifiquement
objet code>. Tandis que tout est compatible avec
objet code>, tout n'est pas compatible avec
? Code> où
? Code> étend
objet code> .
FOO > code> devrait générer une erreur: p>
i code> est un
integer code>, il n'y a aucun moyen que le compilateur devrait autoriser
foo1.foo (i) Pour compiler. P>
Foo<Object> foo4 = new StringFoo();
Compilateurs ne peut pas i> traiter les types bruts comme des erreurs, voir le JLS
@Daniel - En Eclipse, vous pouvez définir le compilateur pour traiter l'utilisation de types bruts comme erreurs. Vous pouvez également définir la plupart des compilateurs pour traiter tous les avertissements comme étant des erreurs et des compilateurs peuvent certainement avertir l'utilisation des types bruts.
Elaborer: Si vous utilisez foo code> comme type brut i> (c'est-à-dire sans paramètre de type), cela (a) générera un avertissement de compilation (que vous pouvez Ignorer), (b) Cause Le compilateur d'utiliser
objet code> pour tous les types génériques et (c) empêchent le compilateur de vérifier les paramètres de type pour l'exactitude dans le contexte d'autres génériques. Par exemple,
foo
foo
Classcastexception code> au moment de l'exécution si les types sont faux. Ceci est indésirable, alors n'utilisez pas de types bruts.
Eh bien, en raison de l'effacement de type, tout ce qui est liée aux génériques est compilé uniquement; Je suppose que c'est ce que vous appelez syntaxtique.
Je pense que votre évaluation initiale est correcte et la différence réelle est que cela en fait une variable typée générique et la FOO ordinaire. P>
Considérez ces types:
Liste code> li>
-
Liste CODE> LI>
-
Liste code> li>
ul> même si string code> est un sous-type de charcuternence code> qui est un sous-type de objet code>, ces types de liste n'ont pas de Relations de sous-type-Superype. (Curieusement, string [] code> est em> un sous-type de Chaluquant (] code> qui est un sous-type de objet [] code>, Mais c'est pour des raisons historiques.) p> Supposons que nous voulions écrire une méthode qui imprime une liste. Si nous faisons p> xxx pré> Ceci ne pourra pas imprimer une liste code> (sans hacks), depuis une liste code> n'est pas une liste code>. Mais avec des caractères génériques, nous pouvons écrire p> xxx pré> et transmettre n'importe quelle liste. P>
wildcards peut avoir des limites supérieure et inférieure pour une flexibilité supplémentaire. Disons que nous voulons imprimer une liste qui ne contient que charcuternence code> s. Si nous faisons p> xxx pré> , nous rencontrons le même problème - nous ne pouvons que le transmettre une liste code> et notre liste code> n'est pas une liste code>. Mais si nous faisons plutôt p> xxx pré> , nous pouvons transmettre cette liste list code> et une liste code> code >, et ainsi de suite. p> p>
L'objet est le Superype de tous types de Java. Cependant, FOO n'est pas le super-espèce de tous foo. Le superype de tous foo est foo. Voir http://docs.oracle.com/javase/Tutorial/extra/ Generics / Wildcards.html Pour plus de détails. P>
Le caractère générique dans un exemple concret strong> em>: p> Vous pouvez attribuer n'importe lequel Sorte de si vous avez une liste Ce code peut fonctionner sur n'importe quel type de liste souhaitée, une liste si la signature était foo > code> indique que dans la portée actuelle, vous ne savez pas ou ne vous souciez pas de quel type de 'foo' vous avez.
FOO > code> et
foo Extend Object> code> sont les mêmes (le premier est sténographique pour l'autre).
foo
Liste code> à la liste
> code>
par exemple p>
> code> Vous pouvez appeler
taille () code> parce que vous n'avez pas besoin de Pour savoir quel type de liste il est de trouver sa taille. Et vous pouvez appeler
obtenir (i) code> car nous savons que la liste contient une sorte d'objet code> code>, le compilateur le traitera comme si
obtenir code> retour et
objet code>.
Mais vous ne pouvez pas appeler ajouter (o) code> car vous ne savez pas (et que le compilateur ne sait pas) Quel type de liste que vous avez affaire.
Dans notre exemple ci-dessus, vous ne voudriez pas autoriser list1.add (nouvel objet ()); code> parce que c'est censé être une liste de
chaîne code> s p> < P> La raison des caractères génériques est donc vous pouvez faire des choses comme ceci: p>
list
,
code> code>, etc. p>
Statique Boolean contenant (Liste
list
list
En supposant que ce sont des erreurs de compilation?
@andrewcooke ce code serait valide; Cependant, étant donné que l'objet serait stocké dans une variable
FOO > code>, il ne saurait pas sur le paramètre
string code>. Par conséquent, si
foo code> a des méthodes qui prennent des arguments de type
t code>, la seule valeur autorisée serait
null code>, et s'il a des méthodes que Retour
t code>, il est traité comme
objet code>.
Désolé, j'ai supprimé mon commentaire avant de voir votre réponse. suis maintenant confus. Quand le travail de capture fonctionne-t-il?
Oh, d'accord, Capture ne correspond que exactement avec lui-même. C'est évident maintenant je vois l'erreur du compilateur dans un code de test ...