2015-06-30 12 views
6

Poniższy kod zawiera błąd "generic array array".Dlaczego nie mogę utworzyć tablicy z wewnętrzną klasą typu ogólnego?

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() { 

     } 
    } 
} 

Zastanawiam się, dlaczego tak jest, ponieważ klasa Entry nie jest rodzajowy klasy i nie ma obiektów typu rodzajowego.

Czy to dlatego, że klasa wewnętrzna nadal ma dostęp do typów ogólnych, nawet jeśli nie używa żadnych? To najlepsze, co mogę wymyślić, ale jeśli tak, to nie rozumiem, dlaczego Java nie może wyglądać i nie używa generycznych typów i dlatego nie jest klasą generyczną?

I tak, widziałem wiele wątków na temat tablic typu rodzajowego, ale nie, nie znalazłem ani jednego dotyczącego klas wewnętrznych.

Odpowiedz

6

Typ jest w rzeczywistości TestClass<K, V>.Entry (tak, ponieważ jest to wewnętrzna klasa). Problem ten można rozwiązać poprzez przekształcenie go w zagnieżdżonej klasy statycznej:

private static class Entry { 
    public Entry() { 

    } 
} 
+0

... idealny, ma sens :) dzięki, będzie oznacz jako poprawną, kiedy mi pozwala. – andy

4

to o co JLS mówi o wyrażeniu array-utworzenia:

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

JLS 15.10.1:

Jest to błąd kompilacji, jeżeli ClassOrInterfaceType nie oznacza a podatkowego typu (§4.7). W przeciwnym razie nazwa ClassOrInterfaceType może oznaczać dowolny nazwany typ odniesienia, nawet typ abstrakcyjnej klasy (§8.1.1.1) lub typ interfejsu .

JLS 4.7:

typ jest reifiable wtedy i tylko wtedy, gdy przynajmniej jeden z poniższych:

  • Odnosi się do zgłoszenia typu klasy nierodzajową lub interfejsu.

  • Jest to typ sparametryzowany, w którym wszystkie argumenty typu są nieograniczone symbole wieloznaczne (§ 4.5.1).

  • Jest to surowy typ (§ 4.8).

  • Jest to typ pierwotny (§ 4.2).

  • Jest to typ tablicy (§ 10.1), którego typ elementu jest możliwy do przeliczenia.

0

Entry jest niestatyczny grupa wewnętrzna. Oznacza to, że znajduje się w zakresie ogólnych parametrów klasy zewnętrznej. Za każdym razem, gdy właśnie piszesz niewykwalifikowane Entry wewnątrz TestClass, oznacza to domyślnie TestClass<K,V>.Entry, który jest parametryzowanym typem! Jak wiesz, nie możesz tworzyć tablic sparametryzowanego typu, np. nie możesz wykonać new ArrayList<String>[5].

Zazwyczaj obejście tworzenia tablic typu sparametryzowanego jest utworzyć tablicę surowego typu zamiast, tj new ArrayList[5] lub tablicę typu wieloznaczne-parametryzowane, tzn new ArrayList<?>[5]. Ale w tym przypadku, jaki jest typ surowy? Odpowiedź jest taka, że ​​należy jednoznacznie zakwalifikować Entry z surowym zewnętrznej typu Klasa:

entry = new TestClass.Entry[10]; 

lub na przemian z typu wildcard-parametryzowane:

entry = (Entry[])new TestClass<?>.Entry[10]; 
Powiązane problemy