有没有更简洁的方法来初始化这个通用数组?

时间:2009-08-12 21:30:32

标签: java arrays generics

昨天我试图创建一个对象数组,属于泛型类的非静态内部类。似乎没有好办法。


首次尝试:

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

这不起作用,因为'Wibble'上下文中的'Bar'是隐式通用的,导致以下错误:

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

这不起作用,因为数组只能从最新的已知非泛型类型转换为泛型类型。对于通用Bar,最近已知的非泛型类型是非泛型Bar,它不能(容易地?)在父类的上下文中引用。导致以下错误:

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

同样有效,并认为我还可以发帖。它仍然很难看,并且没有理由认为普通语法不起作用。

3 个答案:

答案 0 :(得分:2)

如果你还将Bar声明为静态类,那么下面的代码(即最明显的代码)将在编译和运行时都有效:

Bar[] bar = new Bar[11];

修改

使用java.lang.reflect.Array.newInstance是在运行时分配新通用数组的首选方法

答案 1 :(得分:2)

如果您需要保持“隐式通用性”,即您不能使该类保持静态,则可以执行Bar[] bar = new Bla.Bar[11];,但您会收到警告。

答案 2 :(得分:1)

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

排序(呃,有序)。