编程错误实例的剖析[2]内部非静态类的反射
来源:互联网 发布:网络重生txt全集下载 编辑:程序博客网 时间:2024/05/15 09:14
内部非静态类的反射
尽管在之前的学习中,对各种内部类的全限定名有着完善的总结:这里
但今天还是栽了跟头。
本次的案例是这样的,在试图对一个空参构造的内部类进行反射时,出现了错误。
package com.thrblock.moretest;public class Main {class Inner{public Inner(){}}public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {Class<?> c = Class.forName("com.thrblock.moretest.Main$Inner");Object inner = c.newInstance();System.out.println(inner.getClass());}}
运行结果:
Exception in thread "main" java.lang.InstantiationException: com.thrblock.moretest.Main$Inner
package com.thrblock.moretest;public class Main {class Inner{public Inner(){}}public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {Class<?> c = Class.forName("com.thrblock.moretest.Main$Inner");System.out.println(c.getConstructors()[0].getParameterTypes().length);}}运行结果:
1
Inner类明明被声明成空参构造,那这个多出来的参数是什么呢?笔者回想了一些非静态成员内部类的实例化过程,应该是包装类.new 内部类(构造参数…);也就是说,除了我们定义的构造参数外,还需要一个对应包装类的实例,因此猜测多出来的构造参数对应于这个实例,验证一下,果然如此:
package com.thrblock.moretest;public class Main {class Inner{public Inner(){}}public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {Class<?> c = Class.forName("com.thrblock.moretest.Main$Inner");System.out.println(c.getConstructors()[0].getParameterTypes()[0]);}}运行结果:
class com.thrblock.moretest.Main
那么,非静态内部类的反射应该追加一个对应外部类的实例:
package com.thrblock.moretest;import java.lang.reflect.Constructor;import java.lang.reflect.InvocationTargetException;public class Main {class Inner{public Inner(){}}public static void main(String[] args){Class<?> c;try {c = Class.forName("com.thrblock.moretest.Main$Inner");Constructor<?> con = c.getConstructor(Main.class);Inner in = (Inner)con.newInstance(new Main());System.out.println(in.getClass());} catch (ClassNotFoundException | NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {System.out.println("Error happend");}}}运行结果:
class com.thrblock.moretest.Main$Inner
这里已经出,反射成功的拿到对应内部类的实例了。
但问题还没有结束,既然使用$作为类名是合法的,那么假如我自己起一个和内部类相同名字的类会怎样呢:
package com.thrblock.moretest;class Main$Inner {//ERROR:The type Main$Inner is already definedpublic Main$Inner(Main a){}}恩,编译器报错了,显然其检测到了我们的内部类。
也许是我eclipse的问题,如果构造器参数不使用Main类型,那么就绕过了这个错误,在测试时,实际反射到的内部类取决于最后修改的类,即发生了名称冲突进行了class文件覆盖,而此时eclipse没有给出任何提示。
其实也不能将责任推给编译器,在我试图创建带"$"的类时,编译器提示不建议在自建类中使用该符,虽然$可以作为类名,我们在开发中也要慎用。
0 0
- 编程错误实例的剖析[2]内部非静态类的反射
- 编程错误实例的剖析[3]Map的keySet遍历
- 非静态实例的初始化
- 非静态实例的初始化
- java内部静态类和非静态类,和他们在外部的定义
- 编程错误实例的剖析[1]内存不足与GC的错误用法
- 类的内部实例
- Handler 非静态内部引起的内存泄漏问题
- 内部静态类的优点
- 无法反射创建类实例错误的解决
- Java:内部非静态类访问外部类成员的方法
- 显示的静态初始化和非静态实例初始化
- 静态变量和非静态(实例)变量的区别
- 利用反射分析类的内部数据
- 通过反射调用类内部的方法
- 反射得到类的内部信息
- 静态方法的内部可以不可以调用非静态的方法吗?
- 深入浅出剖析静态方法和实例方法的区别
- APEC随感
- 农村广播系统在农村的重要作用
- CTreeCtrl的SetCheck不显示问题
- jquery 全选篇
- 限制别人用wifi 手机就可以
- 编程错误实例的剖析[2]内部非静态类的反射
- 第十一周项目六:回文,素数
- Java_进制转换浅析;
- 11周(回文数)
- Unique Binary Search Trees
- 修改默认模板(dece)将default改为temp
- 当年第几天?
- C#游戏开发快速入门2.2改变游戏对象的状态
- Freemarker应用案例