7

次の問題があります: クラスがあり、リフレクションを使用してその独自の保護されたメソッドの 1 つを呼び出そうとしていますが、例外が発生しています: java.lang.IllegalAccessException: メソッドへのアクセスが拒否されました

誰かがこれに光を当てることができますか?

基本クラス:

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

}

派生具象クラス:

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

2 に答える 2

17

Protected methods are accessible just from the package, the the class itself or the classes that extends it.

As far as I can suppose (based on the Exception) your extended class (MyReceiver) is in another package then the super class (BaseReceiver). Meaning:

  1. MyReceiver and BaseReceiver isn't in the same package;
  2. BaseReceiver doesn't extends MyReceiver;

Now, as you can see on your code, you are doing: method = this.getClass().getDeclaredMethod("testMethod"); this seems ok, but it isn't what you intend. As this method will return MyReceiver.testMethod() method, and this is not accessible from BaseReceiver (as you can see you are using this.getClass(), what returns the instance class, in this case MyReceiver).

You could do something:

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

with this you are instructing that you want the protected method being declared on BaseReceiver class. Of course when you invoke it later with method.invoke(this); you will invoke the overridden method.

But it doesn't make sense to use reflection in such case, as you have testMethod() available, and invoking it (simple as this.testMethod()) you will invoke the overridden one.

Another possibility is to setAccessible(true) on the method like:

method = getClass().getDeclaredMethod("testMethod");
method.setAccessible(true);
method.invoke(this);
于 2012-06-24T09:17:42.130 に答える
1

inの静的型はthisBaseReceiverあるBaseReceiverため、通常は にアクセスできませんMyReceiver.testMethod。それとは別に、リフレクション API は、インスタンスではなく呼び出し元クラスをチェックします (リフレクションの目的を考えると、それ自体が馬鹿げています)。

使えるはずですBaseReceiver.testMethod

リフレクションは、ほとんどの場合 (ただし、すべてではない) 使用される場合は悪い考えです。

于 2012-06-24T14:24:18.503 に答える