Yesterday I attempted to create an array of objects, belonging to a non-static inner class of a generic class. It seems that there is no nice way of doing so.
First attempt:
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{}
}
This does not work, because 'Bar' within the context of 'Wibble' is implicitly generic, resulting in the following error:
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)
Second attempt:
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{}
}
This does not work because arrays can only be cast to a generic type from the most recent known non-generic type. For the generic Bar, the most recently known non-generic type is the non-generic Bar, which cannot (easily?) be referenced within the context of the parent class. Resulting in the following error:
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)
Final attempt:
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{}
}
This works, however, if you wish to create the array within the constructor, you also need a (private) dummy constructor, so that you can get the class.
Furthermore if the parent class is abstract, you need to provide dummy implementations for all of the abstract methods.
As I finished writing this up, I realised that
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{}
}
Works as well, and figured I might as well still post. It's still ugly though, and there's no justification for the fact that normal syntax does not work.