利用反射机制获得非静态内部类之getConstructor的用法探索

 来源: 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,并满足下列任一条件:
意味着若是要使用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。这种方法的设计主要是为了方

便访问标记注释

展开阅读全文

没有更多推荐了,返回首页