You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过反射访问不同包中私有内部类的方法?

问题:跨包反射调用私有内部类的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 04:00:24