2016-07-13 2 views
-1
public class HelloWorld{ 

public static void main(String[] args) { 

    List<? extends Number> callback = new ArrayList<Long>(); 
    new Container<>().test(callback); 
} 

public static class Container<T extends Number> { 

    public void test(List<T> some) { 

    } 

} 

}Génériques - types incompatibles

ce code produit

HelloWorld.java:7: error: incompatible types: List<CAP#1> cannot be converted to List<Number>                                       
     new Container<>().test(callback);                                                    
          ^                                                      
    where CAP#1 is a fresh type-variable:                                                     
    CAP#1 extends Number from capture of ? extends Number 

Pouvez-vous expliquer en détail ce code incorrect.

Je pense que nouveau conteneur sera généralisé avec le type compatible avec rappel

+3

Un peu inutile, puisque 'String' est une classe' final'. – Bohemian

+1

@Bohemian Imaginez que c'est Numéro – gstackoverflow

+0

Dans ce cas, utilisez 'Number', car il existe des raisons valables d'utiliser' Number' dans les génériques mais pas très nombreux pour 'String'. – Makoto

Répondre

1

Tout d'abord, il ne peut pas être un type qui s'étend String comme String est une classe finale.

En second lieu, le compilateur ne peut pas déterminer si le type ? extends SomeType que vous utilisez pour votre List est du même type que T extends SomeType que vous utilisez pour la classe Container, il produit une erreur.

Ce que vous devez faire est soit déclarer un type générique dans la signature de la méthode, et utiliser ce type pour les deux List et Container:

public <T extends SomeClass> void example() { 
    List<T> callback = new ArrayList<>(); 
    new Container<T>().test(callback); 
} 

Ou déclarer la liste avec un type non borné:

List<SomeClass> callback = new ArrayList<>(); 
new Container<>().test(callback); 
+0

ouais, c'est vrai +1 –

+0

Je pense que vous vouliez dire * déclarer la liste avec un type non-borné *, non? – Bohemian

+0

@Bohemian oui, mon mauvais – explv

0

Eh bien, vous utilisez des génériques. Lorsque vous définissez Container, il indique à Container que le constructeur par défaut doit prendre en charge un type qui est l'instance de String. Voici un exemple correct de String qui est sous-classe de Object, donc je l'utilise.

public class HelloWorld{ 

    public static void main(String[] args) { 

     List<String> callback = new ArrayList<String>(); 
     new Container<String>().test(callback); 
    } 

    public static class Container<T extends Object> { 

     public void test(List<T> some) { 

     } 

    } 
} 

J'espère que cela vous aide.