J'ai été très surpris lorsque j'ai remarqué que le code suivant compile sans avertissements et impressions Je m'attendais à une erreur de compilation. P> y a-t-il une raison pour laquelle ce code compile? p> Quel est le moyen correct de s'assurer que les arguments ont le même type? P> EDIT: STRUT> sur les paramètres de type bornés? Le mieux que je puisse penser est celui-ci: p> Malheureusement, Java n'autorise pas les contraintes cycliques. integer / chaîne code>:
4 Réponses :
La raison pour laquelle cela compile est parce que Java déduira la super-type la plus spécifique des arguments passés dans ce cas, dans ce cas, sans génériques: p> même sans génériques, vous pouvez passer dans un Seulement si le type en question est objet code> s>
sérialisable et comparable s'étend sérialisable et comparable s'étend comparable >>> code>, après
1 code> est en boîte sur
integer code> et
"1" code> est transmis comme un
Chaîne code>.
entier code> et un
double code>. p>
final code> pouvez-vous faire cela, sans génériques: p>
public void method(MyFinalClass arg1, MyFinalClass arg2) {
// Yes, they're both MyFinalClasses
}
Java déduit en fait le Superype sérialisable et comparable s'étend sérialisable et comparable s'étend comparable >>> code> dans ce cas.
Il n'est pas possible de le faire. Ou de la regarder d'une autre manière, deux arguments de référence sont toujours "le même type" - La raison sous-jacente à cet égard est qu'il n'ya pas de raison de sécurité pour avoir une telle contrainte. L'un des principaux points d'héritage est qu'il devrait être possible de traiter des instances de sous-classe comme une instance de superclasse en toute sécurité. Un type de référence de type superclasse peut indiquer une instance de cette classe ou sous-classe librement. Par conséquent, deux variables de référence qui ont le même type de compilation, peuvent toujours pointer sur l'exécution à des instances de différents types de sous-classes, totalement en toute sécurité. Donc, vous ne pouvez jamais, lors de la compilation, faire une déclaration sur la relation des classes d'exécution réelles de deux cas, autres que ce sont des sous-classes du type de temps de compilation. Comme il est prudent pour les deux arguments d'être des cas de différentes classes au moment de l'exécution, il peut être moins sûr de passer deux arguments de différents types de temps de compilation. P> objet code> - Tous les arguments de type de référence sont toujours des instances de
objet code>. p>
t code> peut toujours être
objet code> et prendre deux arguments de référence. Même avec
t code> et
u code> peut être
objet code> et prenez donc deux arguments à nouveau. P>
Vous pouvez ajouter la classe sous forme de paramètre supplémentaire.
private static <T> void method(T arg1, T arg2, Class<T> type) { // ... }
Voici comment j'ai résolu ce problème - je voulais créer une méthode qui crée un diff de deux objets.
Naturellement, je voulais que l'O1 et O2 soient du même type. J'ai résolu ceci en encapsulant cette méthode à l'intérieur d'une classe paramétré. P> Ceci peut être utilisé comme:
P> Liste publique
Liste
Vous pouvez indiquer le type générique lorsque vous appelez la méthode:
genericstest. méthode (1, "1"); // ne compilera pas code>