2011-12-16 12 views
7

¿Por qué puedo usar el reflejo para crear una instancia de una clase protegida interna, pero no una clase interna con protección a nivel de paquete? No creo que cualquiera sea accesible fuera del paquete.paquete frente a protección protegida con reflejo de Java

Consideremos el siguiente ejemplo:

package dummy; 

public class ClassContainer { 
    protected static class InnerProtected { 
     public InnerProtected() {} 
    } 

    static class InnerDefault { 
     public InnerDefault() {} 
    } 

    private class InnerPrivate { 
     public InnerPrivate() {} 
    } 
} 


package driver; 

public class DriverClass { 

    public static void main(String[] args) throws Exception { 
     Class.forName("dummy.ClassContainer$InnerProtected").newInstance(); 
     Class.forName("dummy.ClassContainer$InnerDefault").newInstance(); 
     Class.forName("dummy.ClassContainer$InnerPrivate").newInstance(); 
    } 
} 

en cuenta que las dos clases están en diferentes paquetes.

Funciona la primera línea en main (que crea instancias de InnerProtected).

La segunda línea (que crea la instancia de InnerDefault) tiros esta excepción:

Exception in thread "main" java.lang.IllegalAccessException: Class driver.DriverClass can not access a member of class dummy.ClassContainer$InnerDefault with modifiers "public" 

Ya que el controlador es un un paquete diferente que las definiciones de clase, en caso de no ambos intentos de crear instancias de las clases fracasan?

(Por si sirve de algo: Si se intenta crear una instancia de InnerPrivate no lo que cabe esperar:.

Exception in thread "main" java.lang.InstantiationException: dummy.ClassContainer$InnerPrivate 
+0

Interesante pregunta. Esto huele como un error de Java o una decisión de diseño realmente esotérica para mí. – Nayuki

Respuesta

4

Realmente, javap informes que InnerProtected se compila como public, mientras que otras clases miembros son paquete-privada

Creo que es causado por la necesidad de hacerlo visible para las subclases de ClassContainer de diferentes paquetes. Quizás VM no puede manejar las reglas de control de acceso en este caso, para que se manejen en el nivel del compilador.

Tenga en cuenta, sin embargo, que si omite declaraciones de constuctor para estas clases sus constructores generados tendrían sus visililities esperadas, es decir protected, por defecto y private respectivamente.

+1

Sí, JDK 1.00 no tiene clases 'protected', por lo que los archivos de clase tampoco. Debería encontrar que puede acceder a clases internas privadas, e incluso locales, desde el mismo paquete. –

Cuestiones relacionadas