2011-09-27 13 views
14

¿Por qué el siguiente código tiene un error de compilación:No encontraste parámetro de tipo si es una clase interna de la subclase en Java

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(); 
    } 
} 

Compilación de los segundos resultados de la clase en:

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

¿Hay alguna forma de evitar este problema además de poner la clase interna en su propio archivo?

+0

Esta es una pregunta interesante ... No estoy seguro de que el lenguaje lo permita, ya que los genéricos de Java se implementan mediante borrado de tipo. Espero que tengas que hacer de MyFooInner una clase de nivel superior. –

Respuesta

24

Usar la siguiente notación:

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

ACTUALIZACIÓN: clases anidadas estáticas son efectivamente una clase de nivel superior como se especifica 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.

Por lo tanto, la única forma en que puede referirse a una la clase estática anidada está mencionando su clase padre en alguna parte. De lo contrario, es una referencia a una clase importada o a una clase dentro del mismo paquete.

ACTUALIZACIÓN: Para explicar aún más, otra manera de hacer referencia a la clase es la importación de esta manera:

import my.package.MyFoo.MyFooinner; 

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

¿Puedes * explicar * también? ¿O fue solo una conjetura afortunada? – BalusC

+0

+1 pero por favor explícalo que es muy interesante. – Heisenbug

+2

Esa es la forma habitual de referirse a clases anidadas estáticas: http://download.oracle.com/javase/tutorial/java/javaOO/nested.html –

2

para construir sobre @Andrey Adamovich's answer, la razón de esto es que los tipos identificados en una clase la declaración debe tener sentido para los miembros fuera de esa clase. Esto es lo mismo que si tuviera escrito lo siguiente en otro archivo de clase:

MyFooInner mfi = new MyFooInner() 

Esto no sería compilar porque esa clase no sabría lo que era MyFooInner - Me sea necesario para calificarlo o escribiendo MyFoo.MyFooInner de lo contrario, use import MyPackage.MyFoo.MyFooInner;. La misma lógica se aplica a las declaraciones de clase.

Por la misma razón, las clases anidadas que se declaran private no se pueden utilizar en absoluto en la declaración de la clase padre.

Cuestiones relacionadas