调用java子类保护方法时方法访问被拒绝

时间:2012-06-24 07:25:07

标签: java reflection methods illegalaccessexception

我有以下问题:我有一个类,尝试使用反射来调用其受保护的OWN方法之一,并且我得到一个异常: 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
    }
}

2 个答案:

答案 0 :(得分:17)

只需从包,类本身或扩展它的类中访问受保护的方法。

据我所知(基于Exception)你的扩展类(MyReceiver)在另一个包中,然后是超类(BaseReceiver)。含义:

  1. MyReceiverBaseReceiver不在同一个包中;
  2. BaseReceiver未展开MyReceiver;
  3. 现在,正如你在代码中看到的那样,你正在做:method = this.getClass().getDeclaredMethod("testMethod");这似乎没问题,但这不是你想要的。由于此方法将返回MyReceiver.testMethod()方法,并且无法从BaseReceiver访问(正如您所看到的那样使用this.getClass(),因此返回实例类,在本例中为{{1} })。

    你可以做点什么:

    MyReceiver

    有了这个,你指示你希望在... method = BaseReceiver.class.getDeclaredMethod("testMethod"); ... 类上声明受保护的方法。当然,当您稍后使用BaseReceiver调用它时,您将调用重写的方法。

    但是在这种情况下使用反射是没有意义的,因为你有method.invoke(this);可用,并且调用它(简单如this.testMethod())你将调用被覆盖的那个。< / em>的

    另一种可能性是testMethod()方法如下:

    setAccessible(true)

答案 1 :(得分:1)

thisBaseReceiver的静态类型为BaseReceiver,因此您通常无法访问MyReceiver.testMethod。除此之外,反射API检查调用者类,而不是实例(考虑到反射是什么,这是坚果本身。)

您应该可以使用BaseReceiver.testMethod

在使用它的大多数(但不是全部)情况下,反思是一个坏主意。