2010-11-16 9 views
0

Je n'arrive pas à comprendre les subtilités des génériques Java avec des caractères génériques. spécifiquement, pourquoi ne compile-t-il pas?Génériques Java avec caractères génériques ne compilant pas

public class Test { 

    abstract class Function<A, B> { 
     abstract B call(A a); 
    } 

    interface PropertyType { 
     String bubbles(); 
    } 

    class Apartment implements PropertyType { 
     @Override 
     public String bubbles() { 
      return "bubbles"; 
     } 
    } 

    public void invokeFunctionOnAList() { 
     List<Apartment> apts = new ArrayList<Apartment>(); 
     functionLoop(apts, new Function<Apartment, String>() { 

      @Override 
      String call(Apartment a) { 
       return a.bubbles(); 
      } 
     }); 
    } 

    public void functionLoop(List<? extends PropertyType> list, Function<? extends PropertyType, String> t) { 
     for (PropertyType p : list) { 
      t.call(p); 
     } 
    } 
} 
+0

Je peux voir le problème, et la plupart des compilateurs Java seront assez explicites à ce sujet. Quelles erreurs obtenez-vous? – PaulJWilliams

+3

Si vous signalez que quelque chose ne parvient pas à être compilé, vous devez toujours inclure le message d'erreur et l'emplacement. –

Répondre

1

Votre compilateur ne sait pas si vous utilisez le même type dans la liste et la fonction. Par conséquent, vous devez lui dire cela.

Essayez ceci:

public <C extends PropertyType>void functionLoop(
         List<C> list, Function<C, String> t) { 
    for (C p : list) { 
    t.call(p); 
    } 
} 
+0

Oh je vois, parce que le sous-type de la liste ne doit pas être le sous-type de la fonction? – monkjack

+0

Oui, le type d'objets dans votre liste doit avoir le même type de votre paramètre dans votre méthode d'appel dans la fonction. –

0

parce call(Apartment a) devrait obtenir l'objet Apartment comme paramètre et vous passez un objet PropertyType. Alors que Apartment est-PropertyType, mais PropertyType est-NOT-un Appartment.

3

La façon la plus formellement correct de mettre ce code est en fait

public <C extends PropertyType> void functionLoop(
     List<C> list, Function<? super C, String> t) { 
    for (C p : list) { 
     t.call(p); 
    } 
} 

La meilleure explication des génériques que j'ai trouvé sur "Effective Java" par Joshua Bloch. Vous pouvez trouver un petit extrait qui peut se rapporter à votre exemple dans ce presentation.