2012-06-24 24 views
7

Tengo el siguiente problema: Tengo una clase, intento usar el reflejo para llamar a uno de sus PROPIOS métodos protegidos, y obtengo una excepción: java.lang.IllegalAccessException : método de acceso a negaracceso a método denegado al llamar al método protegido de la subclase java

puede alguien tal vez arrojar alguna luz sobre esto?

La clase 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 clase concreta derivada:

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

¿Funciona con 'BaseReceiver.class.getDeclaredMethod'? – Thilo

+0

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

+0

@KazekageGaara: esa otra pregunta se trata de métodos a los que no se puede acceder de otra forma. Aquí, él trata de llamar a su propio método. – Thilo

Respuesta

15

Protegida métodos son accesibles sólo desde el paquete, el la propia clase o las clases que se extiende ella.

Por lo que puedo suponer (basado en el Exception) su clase extendida (MyReceiver) está en otro paquete y luego en la superclase (BaseReceiver). Significado:

  1. MyReceiver y BaseReceiver no está en el mismo paquete;
  2. BaseReceiver no se extiende MyReceiver;

Ahora, como puede ver en su código, usted está haciendo: method = this.getClass().getDeclaredMethod("testMethod"); esto parece correcto, pero no es lo que pretende. Como este método devolverá MyReceiver.testMethod() método, y esto no es accesible desde BaseReceiver (como se puede ver que está utilizando this.getClass(), lo que devuelve la clase ejemplo, en este caso MyReceiver).

Se podía hacer algo:

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

con esto está indicando que desea que el método protegido que se declaró en BaseReceiver clase. Por supuesto, cuando lo invoque más tarde con method.invoke(this); invocará el método reemplazado.

Pero no tiene sentido utilizar la reflexión en este caso, ya que tiene testMethod() disponible, e invocarlo (tan simple como this.testMethod()) invocará el reemplazado.

Otra posibilidad es setAccessible(true) en el método como:

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

+1 'setAccessible (true)' – Bohemian

+0

+1 Simplemente llame 'testMethod()' directamente. La reflexión es una mala idea aquí. –

1

El tipo estático de this en BaseReceiver es BaseReceiver, por lo que normalmente no tienen acceso a MyReceiver.testMethod. Además de eso, las API de reflexión comprueban la clase de llamante, no la instancia (lo cual es extraño para la reflexión).

Usted debe ser capaz de utilizar BaseReceiver.testMethod.

La reflexión es una mala idea en la mayoría (pero no todos) de los casos se utiliza.

Cuestiones relacionadas