2011-09-27 9 views
14

Dlaczego następujący kod ma błąd kompilacji:nie można odnaleźć parametr typu, jeśli jest to wewnętrzna klasa podklasy w Javie

Foo.java:

public abstract class Foo<T> { 
    public abstract T getInner(); 
} 

MyFoo.java:

public class MyFoo extends Foo<MyFooInner> { 
    public static class MyFooInner { 
    } 
    public MyFooInner getInner() { 
     return new MyFooInner(); 
    } 
} 

Kompilacja drugich wyników klasy w:

MyFoo.java:1: cannot find symbol 
symbol: class MyFooInner 
public class MyFoo extends Foo<MyFooInner> { 
          ^
1 error 

Czy istnieje sposób obejścia tego problemu, poza umieszczeniem klasy wewnętrznej we własnym pliku?

+0

To interesujące pytanie ... Nie jestem pewien, czy pozwala na to język, ponieważ Java Generics jest implementowana poprzez usuwanie typów. Spodziewałbym się, że będziesz musiał uczynić z MyFooInner klasę najwyższego poziomu. –

Odpowiedz

24

Użyj następującego oznaczenia:

public class MyFoo extends Foo<MyFoo.MyFooInner> {... 

UPDATE: Statyczne klasy zagnieżdżone są skutecznie najwyższej klasy poziom określony here:

A static nested class interacts with the instance members of its outer class (and other classes) just like any other top-level class. In effect, a static nested class is behaviorally a top-level class that has been nested in another top-level class for packaging convenience.

Więc jedynym sposobem można odnoszą się do klasa zagnieżdżona statyczna wymienia gdzieś swoją klasę macierzystą. W przeciwnym razie jest to odwołanie do importowanej klasy lub do klasy w tym samym pakiecie.

UPDATE: Aby wyjaśnić to jeszcze bardziej, innym sposobem, aby odwoływać się do klasy jest import to tak:

import my.package.MyFoo.MyFooinner; 

public class MyFoo extends Foo<MyFooInner> {... 
+3

Czy możesz także * wyjaśnić * to? A może było to tylko nieoczekiwane, dzikie domysły? – BalusC

+0

+1, ale proszę wyjaśnij to, co jest bardzo interesujące. – Heisenbug

+2

To jest zwykły sposób odwoływania się do klas zagnieżdżonych statycznych: http://download.oracle.com/javase/tutorial/java/javaOO/nested.html –

2

Aby zbudować na @Andrey Adamovich's answer, powodem tego jest to, że typy zidentyfikowane w klasie deklaracja musi mieć sens dla członków spoza tej klasy. To jest taka sama, jak gdybym miał napisane następujące w innym pliku klasy:

MyFooInner mfi = new MyFooInner() 

Nie byłoby skompilować dlatego, że klasa nie będzie wiedział, co MyFooInner było - ja albo trzeba zakwalifikować go pisząc MyFoo.MyFooInner lub w innym przypadku użyj import MyPackage.MyFoo.MyFooInner;. Ta sama logika dotyczy deklaracji klas.

Z tego samego powodu klasy zagnieżdżone, które są zadeklarowane jako private, nie mogą być używane w deklaracji klasy macierzystej.

Powiązane problemy