Constructor类
Constructor 提供关于类的单个构造方法的信息以及对它的访问权限。
Constructor 允许在将实参与带有底层构造方法的形参的 newInstance() 匹配时进行扩展转换,但是如果发生收缩转换,则抛出 IllegalArgumentException。
示例代码:
View Code package reflect; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Iterator; public class ReflectTest { /** * @author alan * @param args * @throws Exception */ public static void main(String[] args) throws Exception { /* * Contructor类解析:类的构造方法没有顺序 Constructor 提供关于类的单个构造方法的信息以及对它的访问权限。 * Constructor 允许在将实参与带有底层构造方法的形参的 newInstance() 匹配时进行扩展转换, * 但是如果发生收缩转换,则抛出 IllegalArgumentException。 * * 反射比较占用时间,需要缓存。程序性能下降:查看Class源码 * */ System.out.println("Contructor类解析"); Constructor constructor=String.class.getConstructor(StringBuffer.class); //getConstructor是可变参数,选择构造方法(含一个字符串参数),运行时执行 String string2=(String) constructor.newInstance(new StringBuffer("string"));//通过参数来选择构造方法创建实例。(与构造方法同样类型的变量) System.out.println(string2);// 编译时无措:二进制代码 运行时出错:Exception in thread "main" java.lang.IllegalArgumentException: argument type mismatch //String string3=(String) constructor.newInstance("string");//参数不同,运行时出错 //System.out.println(string3); } } |
Class 的newInstance()方法解析。newInstance ()中调用的newInstance0()方法使用缓存机制来保存默认构造方法的实例。
jdk源码解析:
public T newInstance() throws InstantiationException, IllegalAccessException { if (System.getSecurityManager() != null) { checkMemberAccess(Member.PUBLIC, ClassLoader.getCallerClassLoader(), false); } return newInstance0(); } private T newInstance0() throws InstantiationException, IllegalAccessException { // NOTE: the following code may not be strictly correct under // the current Java memory model. // Constructor lookup if (cachedConstructor == null) { //缓存为空 if (this == Class.class) { throw new IllegalAccessException( "Can not call newInstance() on the Class for java.lang.Class" ); } try { Class<?>[] empty = {}; final Constructor<T> c = getConstructor0(empty, Member.DECLARED);//得到无参的构造方法构造实例对象。 // Disable accessibility checks on the constructor // since we have to do the security check here anyway // (the stack depth is wrong for the Constructor's // security check to work) java.security.AccessController.doPrivileged( new java.security.PrivilegedAction<Void>() { public Void run() { c.setAccessible(true); return null; } }); cachedConstructor = c; //将c缓存起来,下次调用newInstance时,直接读取缓存并返回 } catch (NoSuchMethodException e) { throw new InstantiationException(getName()); } } Constructor<T> tmpConstructor = cachedConstructor; //调用缓存内的实例对象创建tmpConstructor |