如何通过反射访问不同包中私有内部类的方法?
问题:跨包反射调用私有内部类的public方法时触发IllegalAccessException
场景代码
Outer类(含私有内部类)
package reflectiontest.sompackage; import reflectiontest.Interface; public class Outer { private class Inner implements Interface { public int get() { return 4; } } public Interface getInner() { return new Inner(); } }
Interface接口
package reflectiontest; public interface Interface { int get(); }
Main调用类
package reflectiontest; import reflectiontest.sompackage.Outer; import java.lang.reflect.Method; public class Main { public static void main(String[] args) throws Exception { Outer outer = new Outer(); Interface inner = outer.getInner(); System.out.println(inner.get()); Method get = inner.getClass().getMethod("get"); System.out.println(get.invoke(inner)); } }
运行报错日志
4 Exception in thread "main" java.lang.IllegalAccessException: class reflectiontest.Main cannot access a member of class reflectiontest.sompackage.Outer$Inner with modifiers "public" at java.base/jdk.internal.reflect.Reflection.newIllegalAccessException(Reflection.java:394) at java.base/java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:709) at java.base/java.lang.reflect.Method.invoke(Method.java:569) at reflectiontest.Main.main(Main.java:17)
报错核心原因
虽然Inner类的get()方法是public,但Inner本身是私有内部类,类访问权限为private。反射调用时JVM会先检查成员所属类的访问权限:由于Main和Outer$Inner不在同一包,且Outer$Inner不是public类,因此触发权限校验失败。
可行解决办法
1. 开启反射方法的可访问性
直接调用AccessibleObject.setAccessible(true)绕过权限检查,修改Main类的反射代码:
Method get = inner.getClass().getMethod("get"); get.setAccessible(true); // 关闭权限检查 System.out.println(get.invoke(inner));
适合无法修改目标类源码的临时场景。
2. 通过公开接口获取方法(推荐)
既然Inner实现了公开的Interface,直接从接口类获取方法而非实际实现类:
Method get = Interface.class.getMethod("get"); System.out.println(get.invoke(inner));
完全符合Java访问规则,是最规范的解决方案。
3. 修改内部类的访问权限(若有权限改源码)
如果可以修改Outer类的源码,将Inner的访问权限从private改为public或包级私有(同包调用时):
public class Inner implements Interface { public int get() { return 4; } }
内容的提问来源于stack exchange,提问作者pisek
相关产品推荐
相关产品推荐

