2012-06-24 12 views
7

protetto Ho il seguente problema: Ho una classe, cercando di utilizzare la reflection per chiamare uno dei suoi metodi protetti proprio, e sto ottenendo un'eccezione: java.lang.IllegalAccessException : accesso al metodo negatoaccesso negato durante la chiamata metodo java sottoclasse metodo

Qualcuno potrebbe far luce su questo?

La classe di base:

public abstract class BaseReceiver extends BroadcastReceiver { 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     // invoke the correct event method: 
     Method method; 
     try { 
      method = this.getClass().getDeclaredMethod("testMethod"); 
      method.invoke(this); 
     } catch (Throwable ex) { 
      // ... display exception message 
     } 
    } 

    protected void testMethod() { 
    } 

} 

La classe concreta derivata:

class MyReceiver extends BaseReceiver { 
    @Override 
    protected void testMethod() { 
     // display error message 
    } 
} 
+0

Funziona con 'BaseReceiver.class.getDeclaredMethod'? – Thilo

+0

http: // stackoverflow.it/questions/5184284/illegalaccessexception-on-using-reflection –

+0

@KazekageGaara: l'altra domanda riguarda metodi non altrimenti accessibili. Qui, prova a chiamare il suo metodo. – Thilo

risposta

15

protetto metodi sono accessibili solo dal pacchetto, la classe stessa o le classi che estende.

Per quanto posso supporre (in base allo Exception) la classe estesa (MyReceiver) è in un altro pacchetto della classe super (BaseReceiver). Significato:

  1. MyReceiver e BaseReceiver non è nella stessa confezione;
  2. BaseReceiver non si estende MyReceiver;

Ora, come puoi vedere sul tuo codice, stai facendo: method = this.getClass().getDeclaredMethod("testMethod"); questo sembra ok, ma non è quello che intendi. Poiché questo metodo restituirà il metodo MyReceiver.testMethod() e questo non è accessibile da BaseReceiver (come si può vedere si sta utilizzando this.getClass(), cosa restituisce la classe di istanza, in questo caso MyReceiver).

Si potrebbe fare qualcosa:

... 
method = BaseReceiver.class.getDeclaredMethod("testMethod"); 
... 

con questo si indica che si desidera che il metodo protetto viene dichiarato in BaseReceiver classe. Ovviamente quando lo invochi in seguito con method.invoke(this); invocherai il metodo sottoposto a override.

Ma non ha senso utilizzare il riflesso in questo caso, dato che hai testMethod() disponibile e invocandolo (semplice come this.testMethod()) invocherai quello sottoposto a override.

Un'altra possibilità è quella di setAccessible(true) sul metodo come:

method = getClass().getDeclaredMethod("testMethod"); 
method.setAccessible(true); 
method.invoke(this); 
+4

+1 'setAccessible (true)' – Bohemian

+0

+1 Basta chiamare 'testMethod()' direttamente. La riflessione è una cattiva idea qui. –

1

Il tipo statico di this in BaseReceiver è BaseReceiver, in modo che normalmente non hanno accesso a MyReceiver.testMethod. Oltre a ciò, le API di reflection controllano la classe del chiamante, non l'istanza (che è fuori di sé considerando quale sia la riflessione).

Dovresti essere in grado di utilizzare BaseReceiver.testMethod.

La riflessione è una cattiva idea nella maggior parte (ma non in tutti) i casi in cui viene utilizzata.

Problemi correlati