概述
来源: http://blog.163.com/qhasilver@126/blog/static/161553399201291311119821/
提问关于反射机制拿到内部类的构造方法的问题。总结一下个人学习新东西的过程。
import java.lang.reflect.*; public class Test1 { public static void main(String[] args) throws Exception { Class cls = Test1.Person.class; System.out.println(cls);//这句话的打印说明已经拿到了内部类的字节码对象。 Constructor con = cls.getConstructor(null); System.out.println(con.getName()); System.out.println(con.getModifiers()); } //内部类 class Person{ private String name; public Person(){} } }
Constructor con = cls.getConstructor(null);这一行抛出java.lang.NoSuchMethodException 异常
替换为Constructor con = cls.getConstructors()[0];之后,报错解决了,可究竟为什么用getConstructor就不行呢?
首先查API,搜索getConstructor得到的结果是getConstructor
public Constructor<T> getConstructor(Class<?>... parameterTypes) throws NoSuchMethodException, SecurityException
-
返回一个
Constructor
对象,它反映此Class
对象所表示的类的指定公共构造方法。parameterTypes
参数是Class
对象的一个数组,这些 Class 对象按声明顺序标识构造方法的形参类型。 如果此Class
对象表示非静态上下文中声明的内部类,则形参类型作为第一个参数包括显示封闭的实例。要反映的构造方法是此
Class
对象所表示的类的公共构造方法,其形参类型与parameterTypes
所指定的参数类型相匹配。 -
-
-
参数:
-
parameterTypes
- 参数数组
返回:
-
与指定的
parameterTypes
相匹配的公共构造方法的Constructor
对象
抛出:
-
NoSuchMethodException
- 如果找不到匹配的方法。 -
SecurityException
- 如果存在安全管理器 s ,并满足下列任一条件:- 调用
s.checkMemberAccess(this, Member.PUBLIC)
拒绝访问构造方法 - 调用者的类加载器不同于也不是当前类的类加载器的一个祖先,并且对
s.checkPackageAccess()
的调用拒绝访问该类的包
- 调用
-
意味着若是要使用getConstructors方法得到正确结果,必须传入一个参数parameterTypes。这个参数类型为Class。二话不说,指定为
Constructor con = cls.getConstructor(Test1.Person.class);结果依旧报错。这是何故?
只好继续看API提示,先来个输出语句,看看利用之前获得的cls.getConstructors()[0]究竟是个什么玩意儿?加上下面这条语句
Class[] parameterTypes = con.getParameterTypes(); for(int i = 0; i < parameterTypes.length; i++){ System.out.println(parameterTypes[i]); }
输出结果为:class Test1
既然有了parameterTypes,换回原来的Constructor con = cls.getConstructor(Test1.class);完整代码如下
import java.lang.reflect.*;
public class Test1 { public static void main(String[] args) throws Exception { Class cls = Test1.Person.class; //System.out.println(cls);//这句话的打印说明已经拿到了内部类的字节码对象。 Constructor con = cls.getConstructor(Test1.class);//传入外包装类作为参数 System.out.println(con.getName()); System.out.println(con.getModifiers()); }
// 内部类 class Person { private String name; public Person(){}
} }
这时我们回到API文档中,注意到这么一句话:如果此Class
对象表示非静态上下文中声明的内部类,则形参类型作为第一个参数包括显示封闭的实例。 恰巧有位同学把官方英文版API也贴出来了 include the explicit enclosing instance as the first parameter看到这里,我们可以得到解释,为什么传入的参数不是Test1.Person.class而是Test1.class
果然原版的API表达的意思会更饱满更易懂。这里翻译过来,应该是这个意思:非静态上下文中声明的内部类,应该把外部包装类当做第一个参数,故此应该传入Test1.class
isAssignableFrom 是否父子类
Java Package.isAnnotationPresent()方法用法实例教程。方法返回true,如果
指定类型的注释存在于此元素上, 否则返回false。这种方法的设计主要是为了方
便访问标记注释
最后
以上就是专一宝贝为你收集整理的利用反射机制获得非静态内部类之getConstructor的用法探索的全部内容,希望文章能够帮你解决利用反射机制获得非静态内部类之getConstructor的用法探索所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复