2010-10-15 21 views
3

Je me sens stupide en demandant cela mais je le suis.Java Affectation de référence avec des listes génériques

La ligne List<HasId> ids = list donne une erreur de compilation dans le code suivant:

public class MyGarbageClass { 

    public void myMethod(List<MyCompany> list){ 
     List<HasId> ids = list; 
    } 

    interface HasId { 
     int getId(); 
    } 
    class MyCompany implements HasId{ 
     private int id = 5; 
     @Override 
     public int getId() { 
      return id; 
     } 
    } 
} 

MyCompany implémente Hassid donc je pensais que je devrais pouvoir l'affecter. Pourquoi je ne peux pas? Et plus important encore, ce qui est un moyen facile d'attribuer cela à la liste d'objets HasId.

mise à jour: Liste ids = (List<HasId>)list; pauses aussi sur les types inconvertibles

+0

ce n'est pas non plus une distribution, c'est une référence. Une distribution serait quelque chose comme int a = (int) b; –

+0

@Jeff Storey, j'ai mis à jour la question – Tihom

Répondre

9

La raison pour laquelle une affectation générique comme celle-ci est interdite est qu'il est possible de faire le cast, puis d'ajouter quelque chose à ids qui n'est pas une MyCompany (peut-être MyPerson qui implémente aussi HasId). Donc, si la distribution était autorisée, vous pourriez le faire.

public void myMethod(List<MyCompany> list){ 
    List<HasId> ids = list; 
    ids.add(new MyPerson()); 
} 

Maintenant, la liste a cassé la garantie générique parce que vous avez la liste qui a été déclarée comme <MyCompany> avec un myPerson en elle.

Vous pourriez le lancer comme ceci.

public void myMethod(List<MyCompany> list){ 
    List<? extends HasId> ids = list; 
} 

Mais les opérations add() ne seront pas autorisées, mais vous pouvez l'itérer pour obtenir l'ID si vous le souhaitez.

3

Il est pas permis, car il peut vous permettre de le faire:

List<MyCompany> companies = ...; 
List<HasId> ids = companies; 
ids.add(new HasId() {}); 
MyCompany c = companies.pop(); // <---- Not a MyCompany!!!! 

Vous trouverez peut-être mieux d'utiliser List<? extends HasId>

3

Il est typesafety.

List<HasId> ids ; 

Il est déclaré accepter que la liste des HasId.