使用自定义注解实现反射时遇IllegalAccessException,求解决方案
问题解决:反射调用方法时的IllegalAccessException及编译器异常提示
一、编译器异常提示的处理
编译器提示“unreported exception java.lang.IllegalAccessException; must be caught or declared to be thrown”,是因为Method.invoke()会抛出检查型异常,Java要求必须显式处理,有两种解决方式:
方式1:try-catch捕获异常
把调用invoke()的代码包裹在异常捕获块中,同时还要处理InvocationTargetException(该异常会包装方法内部抛出的异常):
public class AnnotationTest { public static void main(String[] args) { Cat mycat = new Cat("zeus", 10); for(Method method : mycat.getClass().getDeclaredMethods()) { if(method.isAnnotationPresent(RunImmediately.class)) { try { method.invoke(mycat); } catch (IllegalAccessException | InvocationTargetException e) { e.printStackTrace(); } } } } }
方式2:在main方法上声明抛出异常
直接在main方法签名后声明抛出相关异常,把异常处理交给JVM:
public class AnnotationTest { public static void main(String[] args) throws IllegalAccessException, InvocationTargetException { Cat mycat = new Cat("zeus", 10); for(Method method : mycat.getClass().getDeclaredMethods()) { if(method.isAnnotationPresent(RunImmediately.class)) { method.invoke(mycat); } } } }
二、IllegalAccessException的原因与解决
异常原因
getDeclaredMethods()会获取类中所有方法(包括private修饰的私有方法),但反射机制默认不允许访问非公共方法,调用invoke()时就会抛出IllegalAccessException。
解决方法
在调用invoke()之前,调用method.setAccessible(true),强制开启该方法的访问权限:
public class AnnotationTest { public static void main(String[] args) { Cat mycat = new Cat("zeus", 10); for(Method method : mycat.getClass().getDeclaredMethods()) { if(method.isAnnotationPresent(RunImmediately.class)) { method.setAccessible(true); // 允许访问非公共方法 try { method.invoke(mycat); } catch (IllegalAccessException | InvocationTargetException e) { e.printStackTrace(); } } } } }
额外注意点
确保你的自定义注解RunImmediately设置了运行时保留策略,否则反射无法在运行时检测到该注解:
import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @Retention(RetentionPolicy.RUNTIME) public @interface RunImmediately { // 可添加注解属性(如无需求则留空) }
内容的提问来源于stack exchange,提问作者Khaled Osama
相关产品推荐
相关产品推荐

