2012-07-24 4 views
10

Código¿Es una interfaz miembro en una declaración de clase implícitamente pública?

Tengo el siguiente clase con una interfaz de usuario:

package com.example.withinterface; 

public class SomeClass { 

    interface SomeInterface { 

     void doSomething(); 
    } 
} 

Y otra clase tratando de acceder a ella:

package com.example.withinterface.main; 

import com.example.withinterface.SomeClass; 

public class Main { 

    public static void main(String[] argss) { 
     System.out.println(SomeClass.SomeInterface.class); 
    } 
} 

error

En Principal Recibo el siguiente error de javac: SomeInterface is not public in SomeClass; cannot be accessed from outside package.

Y en Eclipse: SomeInterface is not public in SomeClass; cannot be accessed from outside package.

Ambos compilados como Java 7. Todo compila bien si hago SomeInterface public.

Pero Spec dice

El Java Language Specification for Java 7 dice esto:

Una interfaz es una interfaz miembro de cuya declaración está directamente encerrado en otra clase o interfaz de declaración.

Una interfaz miembro en una declaración de clase es implícitamente pública (§6.6) a menos que se especifique un modificador de acceso.

El Java Language Specification for Java 5 no parece tener la segunda oración.

Pregunta

lo tanto no debe ser considerado SomeInterface público y no debería compilar principal?

actualización

Como sugiere Ajay George esto fue hecho an error in the Java Language Specification 7 (gracias JamesB). Mientras tanto, se corrigió la especificación y se eliminó la oración incorrecta. Last version in Archive.org with the incorrect sentence.

+0

Huh. Siempre asumí que todo estaba protegido por paquetes a menos que se indique lo contrario. Supongo que aprendí algo nuevo. –

+1

Creo que esto se debe a que los usuarios que no tienen un modificador de acceso tienen acceso a paquetes. Entonces no pueden ser utilizados por otros paquetes –

+0

@Desolator ¿Leyó la pregunta? Las interfaces de los miembros son ** públicas por defecto **. –

Respuesta

2

Supongo que la especificación es incorrecta. Aquí está el resultado de javap con su código.

E:\workspace>javap com\example\withinterface\SomeClass 
Warning: Binary file com\example\withinterface\SomeClass contains com.example.wi 
thinterface.SomeClass 
Compiled from "SomeClass.java" 
public class com.example.withinterface.SomeClass { 
    public com.example.withinterface.SomeClass(); 
} 

E:\workspace>javap com\example\withinterface\SomeClass$SomeInterface 
Warning: Binary file com\example\withinterface\SomeClass$SomeInterface contains 
com.example.withinterface.SomeClass$SomeInterface 
Compiled from "SomeClass.java" 
interface com.example.withinterface.SomeClass$SomeInterface { 
    public abstract void doSomething(); 
} 

Cambié la interfaz a pública y luego volví a compilarla.

E:\workspace>javap com\example\withinterface\SomeClass 
Warning: Binary file com\example\withinterface\SomeClass contains com.example.wi 
thinterface.SomeClass 
Compiled from "SomeClass.java" 
public class com.example.withinterface.SomeClass { 
    public com.example.withinterface.SomeClass(); 
} 

E:\workspace>javap com\example\withinterface\SomeClass$SomeInterface 
Warning: Binary file com\example\withinterface\SomeClass$SomeInterface contains 
com.example.withinterface.SomeClass$SomeInterface 
Compiled from "SomeClass.java" 
public interface com.example.withinterface.SomeClass$SomeInterface { 
    public abstract void doSomething(); 
} 

Tenga en cuenta la diferencia en la clase interna.

+2

Estoy de acuerdo. El JLS es obviamente incorrecto. Usando Java 7 JDK, el código solo se compila si la interfaz del miembro ** se declara ** explícitamente pública. – JamesB

+0

@JamesB No, la especificación ** no puede ** por definición ser incorrecta. Lo que está mal es la implementación. JLS no es descriptivo, sino ** preceptivo **. –

+0

@MarkoTopolnik parece un error tipográfico: * "Una interfaz miembro en ** una clase ** declaración es implícitamente pública" * probablemente debería ser * "Una interfaz miembro en ** una interfaz ** declaración es implícitamente pública" *. Tendría sentido en el contexto de la oración anterior: * "encerrado en otra clase o declaración de interfaz" *. – assylias

Cuestiones relacionadas