2009-08-12 1 views
1

Hier, j'ai tenté de créer un tableau d'objets, appartenant à une classe interne non statique d'une classe générique. Il semble qu'il n'y a pas de bonne façon de le faire.Existe-t-il une façon plus simple d'initialiser ce tableau générique?


Première tentative:

public class Wibble<T>{ 
     public static void main(String...args){ 
      new Wibble<String>(); 
     } 
     public Wibble(){ 
      Bar[] bar = new Bar[11]; 
     } 
     static class Foo{} 
     class Bar extends Foo{} 
} 

Cela ne fonctionne pas, parce que 'Bar' dans le contexte de 'Wibble' est implicitement générique, ce qui entraîne l'erreur suivante:

Exception in thread "main" java.lang.Error: 
Unresolved compilation problem: Cannot create a generic array of Wibble<T>.Bar 

at Wibble.<init>(Wibble.java:7) 
at Wibble.main(Wibble.java:4) 

Deuxième tentative:

public class Wibble<T> { 
     public static void main(String...args){ 
      new Wibble<String>(); 
     } 
     public Wibble(){ 
      Bar[] bar = (Bar[])new Foo[11]; 
     } 
     static class Foo{} 
     class Bar extends Foo{} 
} 

Cela ne fonctionne pas car les tableaux peuvent uniquement être transtypés en un type générique à partir du type non générique connu le plus récent. Pour la barre générique, le type non générique le plus récemment connu est la barre non générique, qui ne peut pas (facilement?) Être référencée dans le contexte de la classe parente. Résultant l'erreur suivante:

Exception in thread "main" java.lang.ClassCastException: 
[LWibble$Foo; cannot be cast to [LWibble$Bar; 

at Wibble.<init>(Wibble.java:7) 
at Wibble.main(Wibble.java:4) 

tentative finale:

public class Wibble<T> { 
     private static final Class<?> BARCLASS = new Wibble<Object> (false).new Bar().getClass(); 
     public static void main(String...args){ 
      new Wibble<String>(); 
     } 
     private Wibble(boolean flag){} 
     public Wibble(){ 
      Bar[] bar = (Bar[])Array.newInstance(BARCLASS, 11); 
     } 
     static class Foo{} 
     class Bar extends Foo{} 
} 

Cela fonctionne, mais si vous souhaitez créer le tableau dans le constructeur, vous avez également besoin d'un mannequin (privé) constructeur, de sorte que vous pouvez obtenir la classe.
De plus, si la classe parent est abstraite, vous devez fournir des implémentations factices pour toutes les méthodes abstraites.


Comme je l'ai fini d'écrire ce, je réalise que

public class Wibble<T> {  
     public static void main(String...args){ 
      new Wibble<String>(); 
     } 
     private Wibble(boolean flag){} 
     public Wibble(){ 
      Bar[] bar = (Bar[])Array.newInstance(Bar.class, 11); 
     } 
     static class Foo{} 
     class Bar extends Foo{} 
} 

fonctionne aussi bien, et pensé que je pourrais aussi bien encore poster. C'est toujours moche, et il n'y a aucune justification pour le fait que la syntaxe normale ne fonctionne pas.

+0

reformaté, mais quelle est exactement la question? –

+0

Votre premier exemple compile bien pour moi. Je ne suis pas sûr de savoir ce que vous entendez par générique implicite, et il n'y a pas de génériques dans votre exemple. Le débordement de pile supprime-t-il vos "<" and ">"? (utilisez le bouton "formater en tant que code"). –

+0

@Steve B. Etes-vous sûr que vous avez rendu la classe Bar non statique? La classe Bar est générique; Disons que vous avez quelques Wibble wibble, dans wibble toute Barre (étant donné que Bar est une classe interne non statique) a un type générique implicite de «String». –

Répondre

2

si vous déclarez également Bar classe comme statique, puis le code suivant (le plus évident) sera fonctionne à la fois à la compilation et à l'exécution:

Bar[] bar = new Bar[11]; 

EDIT

utilisant java.lang .reflect.Array.newInstance est la méthode préférée pour allouer de nouveaux tableaux génériques à l'exécution

+0

Dans mon code actuel, la classe interne non statique contenait des instances du type générique classes parent, ce qui signifie que Bar ne pouvait pas être statique. En ce qui concerne votre édition, mon problème principal est le fait que le tableau est considéré comme générique du tout. Le type d'exécution du tableau est facilement déductible. Je ne pense pas qu'il devrait y avoir des problèmes quand c'est le cas. –

+0

"using java.lang.reflect.Array.newInstance ..." Non. La classe de composant (Bar) est connue au moment de la compilation. – newacct

2

Si vous devez conserver la "généricité implicite", c'est-à-dire que vous ne pouvez pas rendre la classe statique, yo Vous pouvez faire Bar[] bar = new Bla.Bar[11];, mais vous obtiendrez un avertissement pour cela.

1
List<Bar> bars = new ArrayList<Bar>(); 

Trié (er, ordonné).

Questions connexes