I have the following issue: I have a class, trying to use reflection to call one of its OWN protected methods, and I'm getting an exception: java.lang.IllegalAccessException: access to method denied
Can someone maybe shed some light on this?
The base class:
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() {
}
}
The derived concrete class:
class MyReceiver extends BaseReceiver {
@Override
protected void testMethod() {
// display error message
}
}
Methods marked protected can only be accessed by subclasses and by code in the same package. If you made the method public in both subclass and superclass, calling demoMethod() would call the subclass implementation, regardless whether the reference was of the super or subclass type.
Yes, the protected method of a superclass can be overridden by a subclass. If the superclass method is protected, the subclass overridden method can have protected or public (but not default or private) which means the subclass overridden method can not have a weaker access specifier.
2. The protected Keyword. While elements declared as private can be accessed only by the class in which they're declared, the protected keyword allows access from sub-classes and members of the same package.
No, we cannot override private or static methods in Java.
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:
MyReceiver
and BaseReceiver
isn't in the same package;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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With