2009-08-12 3 views
1

Вчера я попытался создать массив объектов, принадлежащих нестационарному внутреннему классу универсального класса. Кажется, что нет хорошего способа сделать это.Есть ли более чистый способ инициализировать этот общий массив?


Первая попытка:

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{} 
} 

Это не работает, потому что 'Bar' в контексте 'Wibble' неявно родовое, что приводит к следующей ошибке:

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) 

Вторая попытка:

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{} 
} 

Это не работает, потому что массивы могут быть переданы только в общий тип из самого известного известного не общего типа. Для общего бара самым известным не общим типом является не общий шаблон, который нельзя (легко?) Ссылаться в контексте родительского класса. В результате в следующей ошибки:

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) 

Заключительная попытка:

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{} 
} 

Это работает, однако, если вы хотите создать массив внутри конструктора, вы также должны (частный) манекен конструктор, чтобы вы могли получить класс.
Кроме того, если родительский класс является абстрактным, вам необходимо предоставить фиктивные реализации для всех абстрактных методов.


Когда я закончил писать это, я понял, что

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{} 
} 

Работает хорошо, и полагал, что я мог бы также еще сообщения. Тем не менее, это все еще некрасиво, и нет никаких оснований полагать, что нормальный синтаксис не работает.

+0

переформатирован, но в чем вопрос? –

+0

Ваш первый пример компилируется для меня. Я не уверен, что знаю, что вы подразумеваете под импликацией generic, и в вашем примере нет никаких дженериков. Является ли переполнение стека удалением вашего «<" and ">»? (используйте кнопку «формат как код»). –

+0

@Steve B. Вы уверены, что сделали класс Bar нестатичным? Класс Bar является общим; предположим, что у вас есть Wibble wibble, в пределах wibble any Bar (при условии, что Bar нестатический внутренний класс) имеет неявный общий тип 'String'. – 2009-08-12 22:31:18

ответ

2

, если вы объявите также Bar, как статический класс, то следующий код (т.е. наиболее очевидным) будет работает как во время компиляции и во время выполнения:

Bar[] bar = new Bar[11]; 

EDIT

использованием java.lang .reflect.Array.newInstance является предпочтительным способом выделения новых общих массивов во время выполнения

+0

В моем фактическом коде нестатический внутренний класс содержал экземпляры родительских классов generic type, что означает, что Bar не может быть статическим. Что касается вашего редактирования, то моя главная проблема заключается в том, что массив считается общим вообще. Тип среды выполнения легко выводится. Я не думаю, что в этом случае возникнут проблемы. – 2009-08-12 22:42:56

+0

"Использование java.lang.reflect.Array.newInstance ..." Нет. Класс компонента (Bar) известен во время компиляции. – newacct

2

Если вам нужно сохранить «неявную общую», то есть вы не можете сделать класс статическим, лет u может сделать Bar[] bar = new Bla.Bar[11];, хотя вы получите предупреждение за это.

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

Сортировка (по заказу).

Смежные вопросы