Java 反射内部类

Java 反射内部类

 

2018.05.09 23:39 字数 248 阅读 36评论 0喜欢 0

问:如下代码段,已获取外部类实例情况下,如何反射实例化内部类及调用内部类方法?

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();
    }
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值