Why can't I create an array of an inner class of a generic type?

The following code gives the error "create a shared array".

public class TestClass<K, V> { Entry[] entry; private TestClass() { entry = new Entry[10]; // <--- this line gives generic array creation error } private class Entry { public Entry() { } } } 

I am wondering why this happens because the Entry class is not a general class and does not have generic type objects.

Is this because the inner class still has access to the generic types, even if it is not used? This is the best I can come up with, although if it is, I don’t understand why Java cannot look and see that it does not use generic types and therefore is not a generic class?

And yes, I saw a lot of threads about arrays of a typical type, but no, I did not find a single one regarding inner classes.

+6
source share
3 answers

The type is actually TestClass<K, V>.Entry (yes, because it is an inner class). You can solve this by translating it into a nested static class:

 private static class Entry { public Entry() { } } 
+6
source

What about what JLS says about an array creation expression:

 ArrayCreationExpression: [...] new ClassOrInterfaceType DimExprs [Dims] [...] 

JLS 15.10.1 :

This is a compile-time error if ClassOrInterfaceType does not denote a reifiable type (§4.7). Otherwise, ClassOrInterfaceType can call any reference type, even an abstract class type (§8.1.1.1) or an interface type.

JLS 4.7:

A type is reproduced if and only if one of the following conditions is true:

  • It refers to a declaration of a non-generic or interface type.

  • This is a parameterized type in which all type arguments are unlimited wildcards (§4.5.1).

  • This is a raw type (§4.8).

  • This is a primitive type (§4.2).

  • This is an array type (§10.1) whose element type can be re-identified.

+4
source

Entry is a non-static inner class. This means that it is included in the scope of the general parameters of the outer class. Each time you simply write an unqualified Entry inside TestClass , it implicitly means TestClass<K,V>.Entry , which is a parameterized type! As you know, you cannot create arrays of a parameterized type, for example. you cannot make new ArrayList<String>[5] .

Usually a workaround for creating arrays of parameterized type is to instead create an array of the raw type, i.e. new ArrayList[5] , or an array of type with a wildcard parameter, ie new ArrayList<?>[5] . But in this case, what is the raw type? The answer is that you must explicitly qualify Entry with the outer type of the outer class:

 entry = new TestClass.Entry[10]; 

or alternating with a wildcard parameter:

 entry = (Entry[])new TestClass<?>.Entry[10]; 
0
source

Source: https://habr.com/ru/post/990036/


All Articles