2017-03-29 1 views
1

Je regarde les caractères génériques et je les ai compris d'une manière très simple. <? extends Type> quand je les utilise juste pour la lecture (ReturnType) et <? super Type> quand je l'utilise pour écrire (parameterType)simple utilisation de caractères génériques malentendu

interface P<T> { 
    boolean eval(T e); 
} 

public class IsZero implements P<Integer> { 
    public boolean eval(Integer e) { 
     return e.intValue() == 0; 
    } 
} 

public class QQ<T> { 
    public void filter(Q<T> q1, Q<T> q2, P<T> p) { 
     while (!q2.isEmpty()) { 
      T tmp = q2.remove(); 
      if (p.eval(tmp)) { 
       q1.add(tmp); 
      } 
     } 
    } 
} 

Ainsi, ce code donné. Mon professeur a écrit solution suivante:

/* 
Q<? super T> q1 just used as a Parametertype for writing (add) 
Q<? extends T> q2 just used as a Returntype for reading (remove) 
P<? super T> p just used as Parametertype (eval) 
*/ 

Je suis d'accord avec cela, mais je ne peux pas comprendre pourquoi il est P<? super T> depuis eval retourne un booléen? Ou est-ce que je suis dans l'erreur?

+0

Q parce que q1, q2 et p sont autorisés à contenir des sous-classes d'entier et pas seulement entier lui-même ... dans le cas de T = entier. – Wietlol

+0

Désolé, pas les sous-classes mais les parents: D – Wietlol

Répondre

0

p et q1 doivent être Q<? super T> pour la même raison ... parce que les deux doivent être en mesure de poignée une instance de T et si vous êtes capable de gérer T ou l'un de ses superclasses vous êtes bien dans ce ce qui concerne. Donc, la raison de le mettre à Q<? super T> au lieu de Q<T> est de rendre votre code aussi général que possible.

Une autre façon de le mettre ... si X > Y signifie que X est une superclasse/interface Y ou Y lui-même et p est Q<A>, q1 est Q<B> et q2 est Q<C>

Les contraintes ci-dessus que l'état A > C et B > C quelle que soit la relation entre A et B; si au moins l'un d'entre eux est une interface, il se peut qu'il ne soit pas du tout lié.

Peu importe si l'appel de méthode va modifier ou pas le sujet. Par ailleurs, dans la plupart des classes de collections standard Java, add renvoie également une valeur booléenne pour indiquer si l'opération a modifié la collection qui est la plupart du temps ignorée. Donc, ce n'est pas pertinent du tout.