Java 反射内部类

问:如下代码段,已获取外部类实例情况下,如何反射实例化内部类及调用内部类方法?
class OuterClass {
    public void func(){
        System.out.println("Outer class.");
    }
    class InnerClass {
        private String mName;
        public InnerClass(String name) {
            mName = name;
        }
        void getName(){
            System.out.println("name is:"+mName);
        }
    }
}

答:答案完整代码如下:

class OuterClass {
    public void func() {
        System.out.println("Outer class.");
    }
    class InnerClass {
        private String mName;
        public InnerClass(String name) {
            mName = name;
        }
        void getName() {
            System.out.println("name is:"+mName);
        }
    }
}

public class Demo {
    public static void main(String[] args) throws Exception {
        Class outerClass = Class.forName("OuterClass");
        //通过外部类的方法名获取外部类的方法
        Method method = outerClass.getDeclaredMethod("func");
        //调用外部类实例的func方法,invoke第一参数为外部类实例
        method.invoke(outerClass.newInstance());

        //内部类反射名字需要使用$分隔,编译后生成的规则
        Class innerClass = Class.forName("OuterClass$InnerClass");
        //通过内部类的方法名获取内部类的方法
        Method method2 = innerClass.getDeclaredMethod("getName");
        //特别注意!内部类newInstance的第一个参数必须是外部类实例的引用
        method2.invoke(innerClass.getDeclaredConstructors()[0].newInstance(outerClass.newInstance(),"yan"));
    }
}

即便上面 InnerClass 的修饰符是 private,上面的代码依旧可以成功反射,只是不能直接通过

outClass.new InnerClass("yan"); 

的方式去实例化内部类。

但是,当上面 InnerClass 的修饰符如果是 static,即内部类是静态内部类时,上面的代码就不能用了,需要将答案的最后一行代码改成

method2.invoke(innerClass.getDeclaredConstructors()[0].newInstance("yan")); 

才行,因为静态内部类没有持有外部类的任何引用,所以不用传递外部类实例对象的引用。

问:如何反射如下类的匿名内部成员类?
class OuterClass {
    public Runnable runnable = new Runnable() {
        public void run() {
            System.out.println("runnable.");
        }
    };
}

答:这种场景你就不要把它想成匿名内部类了,直接当作外部类的成员变量去反射即可,如下。

class OuterClass {
    public Runnable runnable = new Runnable() {
        public void run() {
            System.out.println("runnable.");
        }
    };
}

public class Demo {
    public static void main(String[] args) throws Exception {
        Class outerClass = Class.forName("OuterClass");
        Runnable runnable = (Runnable) (outerClass.getField("runnable").get(outerClass.newInstance()));
        runnable.run();
    }
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 问:Java 常见的内部类有哪几种,简单说说其特征? 答:静态内部类、成员内部类、方法内部类(局部内部类)、匿名内...
    Little丶Jerry阅读 1,995评论 0 1
  • 这个系列是帮助复习 Java 的基础知识的,但是并不会按照一个特定的顺序。现在开始复习下内部类的相关知识。 0. ...
    一团捞面阅读 661评论 0 0
  • 作者:心随云动 每一次拨通了你的电话号码, 想要对你说的千言万语, 可是话到嘴边, 却都化做了那一句, 我想你了!...
    心随云动阅读 1,199评论 0 0
  • 她很努力,六点起床,去背单词,晚上不到临晨宿舍很少见到她,手机里闹钟从来都是好多个,设置为“每天”,从大一开始各种...
    昨夜西风烈阅读 284评论 0 1