黑马程序员技术交流社区
标题:
反射访问非静态内部类问题
[打印本页]
作者:
王红潮
时间:
2012-9-14 12:47
标题:
反射访问非静态内部类问题
public class Outer {
public static void main(String[] args) throws InstantiationException, IllegalAccessException {
new Outer().test();
}
private void test() throws InstantiationException, IllegalAccessException {
System.out.println(new Inner()); //正常运行
//System.out.println(Outer.Inner.class.newInstance());
System.out.println(Inner.class.newInstance());
}
public class Inner{
public String toString(){
return "Inner case";
}
}
}
复制代码
利用反射调用Inner构造器创建对象,运行异常:Outer$Inner,但前面加了外部类限定Outer.Inner.class.newInstance();依然是运行异常,这里应该怎样才能访问?
作者:
尤圣回
时间:
2012-9-14 13:52
System.out.println(new Inner()); // 正常运行
System.out.println(Inner.class);
//查看class是否有构造函数
System.out.println(Inner.class.getConstructors().length);
//获取第一个构造函数
System.out.println(Inner.class.getConstructors()[0]);
//用构造函数初始化内部类
System.out.println(Inner.class.getConstructors()[0].newInstance(new Outer()));
复制代码
作者:
尤圣回
时间:
2012-9-14 13:53
我这个是用边界法 还有一种就不说了
作者:
尤圣回
时间:
2012-9-14 13:57
在给你一个用反射实例化静态内部类的方法
System.out.println(Inner.class);
//查看class是否有构造函数
System.out.println(Inner.class.getDeclaredConstructors().length);
//获取第一个构造函数
Constructor c = Inner.class.getDeclaredConstructors()[0];
//将c设置成可访问
c.setAccessible(true);
//用构造函数初始化内部类
System.out.println(c.newInstance(new Outer()));
复制代码
抛异常自己解决
作者:
杜佳瑞
时间:
2012-9-14 16:17
楼上的方法是对的,但要是这样解释我估计楼主也看不懂。
首先通过反射创建对象一般有两种方式,第一种就是楼主所用到的Inner.class.newInstance(),但是这种方式必须要求Inner这个类中有一个无参的构造函数。
第二种,就是通过构造方法了,但是怎样得到这个方法呢?如果用Inner.class.getConstructor()也只能得到一个无参的构造函数,楼主可以试一下,运行结果是java.lang.NoSuchMethodException这个异常,说明没找到这个方法。说明这个类没有无参构造函数。第一种方法肯定也是这个结果。
那么只能通过Inner.class.getConstructors()得到所有构造方法了,然后通过.length这个属性检查到只有一个构造方法,那么我们就可以通过Inner.class.getConstructors()[0]可以得到这个构造方法public com.Test.Outer$Inner(com.Test.Outer),可以看出这个方法有一个Outer的参数。再通过这个构造方法就能得到Inner这个类的对象了
要强调的是内部类的字节码很特别,比如说Inner这个类的字节码是Outer$Inner
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2