2010-08-02 15 views
10

Ho due classi.IllegalAccessError: accesso a un metodo protetto

Classe A ha il metodo protetto m(), a è un'istanza di A.

Classe B è nello stesso pacchetto della classe A.

Sto cercando di accesso a.m() ma io sono sempre IllegalAccessError ...

Cosa c'è di sbagliato?

+4

Si prega di produrre un programma breve ma completo che dimostri il problema. Sembra molto strano. Hai qualche offuscamento etc coinvolto? –

risposta

18

Il compilatore deve rilevare errori come questo. Dato che apparentemente si ottiene questo in fase di esecuzione, è successo qualcosa di strano. Probabilmente hai cambiato il codice sorgente ma completamente ricompilato.

Un altro potenziale, ma oscuro, problema è il caricamento delle classi attraverso diversi caricatori di classe. Le classi caricate da caricatori di classi diverse si troveranno in pacchetti diversi anche se il nome del pacchetto è lo stesso (nello stesso modo in cui le classi con lo stesso nome caricate da caricatori di classi diverse saranno di classi diverse).

-1

Si deve lavorare, vedere l'esempio seguente che funziona bene:

package com.stackoverflow; 

public class TEST 
{ 
    static class A { 
    protected void m() 
    { 
     System.out.println("hello from A.m()"); 
    } 
    } 

    static class B { 

    public B() 
    { 
     a.m(); 
    } 

    private A a = new A(); 
    } 

    /** 
    * @param args 
    */ 
    public static void main(String[] args) 
    { 
    B b = new B(); 
    } 
} 

che stampa il messaggio destinato: "hello from A.m()"

"The protected modifier specifies that the member can only be accessed within its own package (as with package-private) and, in addition, by a subclass of its class in another package."

Vedi Controlling Access to Members of a Class.

+2

"Il modificatore protetto specifica che è possibile accedere al membro solo all'interno del proprio pacchetto (come con package-private) e, inoltre, da una sottoclasse della sua classe in un altro pacchetto." http://download.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html –

+0

Oppure lasciarlo con accesso predefinito (vale a dire senza identificatore di accesso) per consentire l'accesso al pacchetto. – Scott

+0

ho cambiato il contenuto della risposta, il contenuto precedente era bacato, mi dispiace per questo e thx @fd; sei sicuro che la tua classe B sia veramente nello stesso pacchetto della classe A? –

-2
Il compilatore

dovrebbe rilevare errori come questo. Come si ottiene questo in fase di esecuzione, è successo qualcosa di sbagliato. Molto probabilmente hai cambiato il codice sorgente che è completamente ricompilato.

Deve funzionare. Ecco un esempio di esecuzione -

**

  • CLASSE A

**

package com.test; 

public class A { 

    protected void m(){ 
    System.out.println("Hi Stackoverflow"); 
} 

} 

**

  • CLASSE B

**

package com.test; 

public class B{ 

public static void main(String[] args) { 
    A a = new A(); 
    a.m(); 
} 

} 

che stampa la stringa previsto

Hi Stackoverflow

15

Questo può accadere se le classi A e B vengono caricati diverso classloader. Jvm considera quindi queste classi in "pacchetti runtime" differenti. Citando the jvm specification, paragrafo 5.3:

At run time, a class or interface is determined not by its name alone, but by a pair: its fully qualified name and its defining class loader. Each such class or interface belongs to a single runtime package. The runtime package of a class or interface is determined by the package name and defining class loader of the class or interface.

E nella sezione 5.4.4:

A field or method R is accessible to a class or interface D if and only if any of the following conditions is true:

...

R is either protected or package private (that is, neither public nor protected nor private), and is declared by a class in the same runtime package as D.

+0

sospetto che questo potrebbe causare il mio problema, ma non sono sicuro di dove nello stack verrà inserito un secondo caricatore di classe o come eseguire il debug. Ma guarderò intorno ... –

+0

Ho trovato questa risposta dopo aver cercato su Google un altro problema in cui la mia classe si trovava nello stesso pacchetto con nome, ma un diverso pacchetto di runtime. Questo rende le cose molto più sensate! +1 – vergenzt

Problemi correlati