2011-12-16 5 views
7

Perché è possibile utilizzare la riflessione per creare un'istanza di una classe protetta interna, ma non una classe interna con protezione a livello di pacchetto? Non penserei che entrambi sarebbero accessibili al di fuori del pacchetto.pacchetto contro protezione protetta con riflessione Java

consideri il seguente esempio:

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

Si noti che le due classi sono in diversi pacchetti.

La prima riga in main (che istanzia InnerProtected) funziona.

La seconda riga (che istanzia InnerDefault) genera questa eccezione:

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

Poiché il driver è un pacchetto diverso rispetto alle definizioni di classe, non dovrebbe entrambi tentativi di istanziare classi sicuro?

(per quello che vale: Il tentativo di creare un'istanza InnerPrivate non come mi sarei aspettato.

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

Interessante domanda. Questo mi ricorda un bug di Java o una decisione di design davvero esoterica per me. – Nayuki

risposta

4

Davvero, javap rapporti che InnerProtected è compilato come public, mentre le altre classi aderenti sono pacchetti-privato

Credo che sia causato dalla necessità di renderlo visibile alle sottoclassi di ClassContainer da diversi pacchetti.Probabilmente la VM non può gestire le regole di controllo degli accessi in questo caso, in modo che siano gestite a livello di compilatore

Si noti, tuttavia, che se si omettono le dichiarazioni del costruttore per queste classi, i loro costruttori generati avranno le loro visibililità previste, ovvero protected, rispettivamente, private e rispettivamente.

+1

Sì, JDK 1.00 non ha classi 'protected', quindi nemmeno i file di classe. Dovresti scoprire che puoi accedere a private, e anche a classi interne locali, dallo stesso pacchetto. –