Java doesn't allow arrays of inner classes for a generic class

I know that you cannot create an array of a generic type, Instead you have to resort to a hack. (Given Java supports generic arrays, just not their creation, it is not clear to me why a hack is better than Java supporting creating generic arrays)

Instead of writing this

Map.Entry<K, V>[] entries = new Map.Entry<K, V>[numEntries];

you have to write this

@SuppressWarnings("unchecked")
Map.Entry<K, V>[] entries = (Map.Entry<K, V>) new Map.Entry[numEntries];

Unfortunately this doesn't work if you have an array of nested type of a generic

public class Outer<E> {
    final Inner[] inners = new Inner[16]; // Generic array creation

    class Inner {
    }
}

The best work around appears to be

@SuppressWarnings("unchecked")
final Inner[] inners = (Inner[]) Array.newInstance(Inner.class, 16);

Is this the most "elegant" solution?


I make seen Generic Array Creation Compilation Error From Inner Class but the solution here is worse IMHO.

Answers


Do the following:

@SuppressWarnings("unchecked")
final Inner[] inners = (Inner[])new Outer<?>.Inner[16];

The equivalent to your first example would have been new Outer.Inner[16] but this will isolate the unchecked cast and avoid the raw type.


What you need to realize is that your situation is the same as the first situation you described.

Inner is a non-static inner class of Outer, a generic class. That means Inner is within the scope of the type parameter, and simply writing Inner is short for Outer<E>.Inner. i.e. it may not look it, but simply Inner is a parameterized type, just like Map.Entry<K, V>, because the type parameter E of the outer class becomes implicitly a type parameter of the inner class. The solution to both problems is the same.

Your solution to the first problem was to create an array of the raw type, i.e. new Map.Entry[numEntries];. What is the raw type here? Not Inner, as we already discussed. Instead, you need to explicitly qualify the outer type to access the raw type: new Outer.Inner[16];. Of course, you need a cast to cast it back into the desired generic array type:

(Inner[])new Outer.Inner[16]

There is another way to create an array of a generic type, without using a raw type -- using a wildcarded type, i.e. new Map.Entry<?, ?>[numEntries];. The equivalent for our case would be new Outer<?>.Inner[16];. With the cast:

(Inner[])new Outer<?>.Inner[16]

Is it an option for you to make the inner class static?

If that is possible you shold be able to create array of the inner class using the standard way:

public class Outer<E> {
    final Inner[] inners = new Inner[16]; // works

    static class Inner {
    }
}

Need Your Help

android-opencv converting mat to grayscale with using matToBitmap/bitmapToMat

android opencv bitmap grayscale

I am using newer opencv library of willowgarage in eclipse. And I want to convert a mat variable into grayscale, I've tried everything I found on the net but they didnt work for me.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.