2010-12-14 9 views
2

Ok Question sur les génériques javas, itérable, et pour chaque boucle. Le problème étant que, si je déclare la classe 'Test' non typée, je perds toutes les informations génériques sur toutes mes fonctions et pour-chacune ne les aime pas du tout.Java classes génériques non typées, supprimant leurs fonctions types génériques

Exemple

public class Test<T> implements Iterable<Integer>{ 

    public Test() {} 

    public Iterator<Integer> iterator() {return null;} 

    public static void main(String[] args) { 
     Test t = new Test(); 

     //Good, 
     //its returning an Iterator<object> but it automatically changes to Iterator<Integer> 
     Iterator<Integer> it = t.iterator(); 

     //Bad 
     //incompatable types, required Integer, found Object 
     for(Integer i : t){ 
     } 
    }Untyped generic classes losing 
} 

Lorsque 'Test t' est non typé, le «itérateur() renvoyée par la fonction de l'itérateur 'au lieu d'un '< itérateur Entier>'.

Je ne suis pas exactement sûr de la raison derrière cela, je sais qu'un correctif pour cela est juste d'utiliser un caractère générique sur 'Test <? > t = nouveau test() '. Cependant, ceci est une solution moins qu'idéale.
Est-il possible d'éditer uniquement la déclaration de classe et ses fonctions et de faire en sorte que la boucle de chaque boucle ne soit pas typée?

+0

Si vous utilisez des types premières, génériques sur les méthodes seront ignorées (voir dernier opus Java Puzzlers). N'utilisez pas de types bruts. Les versions récentes de javac devraient donner des avertissements. –

+0

Merci pour le lien vidéo, des choses très intéressantes dans leur. Le raisonnement derrière le fait sence maintenant. – user542481

Répondre

3

Vous devez juste faire ce qui suit:

public class Test implements Iterable<Integer>{ 

Retirez le type générique tous ensemble. La classe Test n'est pas générique du tout. Il s'agit simplement de mettre en place une interface générique. La déclaration d'un type générique n'est pas nécessaire. Cela aura également l'avantage de supprimer cet avertissement générique que vous receviez.

@Eugene fait un bon point. Si vous voulez vraiment un type générique Test, vous devez déclarer Test comme iterator générique:

Vous devez juste faire ce qui suit:

public class Test implements Iterable<Integer>{ 

Retirez le type générique tous ensemble. La classe Test n'est pas générique du tout. Il s'agit simplement de mettre en place une interface générique. La déclaration d'un type générique n'est pas nécessaire. Cela aura également l'avantage de supprimer cet avertissement générique que vous receviez.

public class Test<T> implements Iterable<T>{ 

Et puis, assurez-vous de faire Test générique lorsque vous instanciation.

Test<Integer> t = new Test<Integer>; 

Ensuite, les appels à for(Integer i: t) seront compilés.

2

Vous devez soit écrire ceci:

public class Test implements Iterable<Integer>{ 
    ... 

ou generify fait votre classe:

public class Test<T> implements Iterable<T> { 

    public Iterator<T> iterator() {return null;} 

    public static void main(String[] args) { 
     Test<Integer> t = new Test<Integer>(); 

     Iterator<Integer> it = t.iterator(); 

     for(Integer i : t){ 
     } 
    } 
} 
+0

Juste ce que je commençais à écrire. +1 –

+0

Yup qui fonctionnerait, mais vous pouvez rencontrer des situations comme. "La classe publique Vertex implémente Iterable >". Pour un exemple de graphique.C'est bizarre mais vous pouvez obtenir la situation où votre itérable ne retourne pas la classe qui l'appelle. Ma faute, je l'ai mal expliqué. – user542481

+0

C'est une question complètement différente. Dans ce cas, votre iterator() méthode devrait retourner Iterator >, aussi simple que cela. D'autre part, vous n'avez pas besoin probablement de clarifier votre mise en œuvre Iterable et peut simplement déclarer plus générique que met en œuvre Iterable au lieu de Iterable >. –

Questions connexes