classUser{ publicUser(){} publicUser(String name){} privateUser(String name, int age){} }
// 获取指定的一个构造器 privatestaticvoidgetOne()throws Exception { // 1. 获取构造器所在类的字节码对象 Class<User> clz = User.class; // 2. 获取 clz 对象中 public User() Constructor<User> con = clz.getConstructor(); System.out.println(con); // public java进阶.com.lizhaoloveit._Constructor.User() // 3. 获取 public User(String name) con = clz.getDeclaredConstructor(String.class); System.out.println(con);// public java进阶.com.lizhaoloveit._Constructor.User(java.lang.String) // 4. 获取 private User(String name, int age) con = clz.getDeclaredConstructor(String.class, int.class); System.out.println(con); // 抛异常 }
// 获取所有的构造器 privatestaticvoidgetAll(){ // 1. 获取构造器所在的字节码对象 Class<User> clz = User.class; // 2. 获取clz对象中所有的构造器 Constructor<User>[] cs = clz.getDeclaredConstructors(); System.out.println(cs.length); for (Constructor<User> c : cs) { System.out.println(c); } // public java进阶.com.lizhaoloveit._Constructor.User() // public java进阶.com.lizhaoloveit._Constructor.User(java.lang.String) // private java进阶.com.lizhaoloveit._Constructor.User(java.lang.String,int) }
使用反射调用构造器创建对象
找到构造器所在的类的字节码对象
获取构造器对象
使用反射,创建对象
Constructor 类的常用方法 public T newInstance(Object... initargs) 如果调用带参构造器,只能使用该方法。 参数: initargs:表示调用构造器的实际参数 返回: 返回创建的实例, T 表示 Class 所代表的字节码对象的类型 如果一个类中的构造器是外界可以直接访问,同时没有参数,可以直接用 Class 类中的 newInstance 方法创建对象。
public Object newInstance() 相当于 new 类名();
Class 类有 newInsatnce() 方法 :创建字节码对象的实例, 等价于 constructor 的 newInstance()方法, 注意:需要当前类有公共的无参构造器方法。
调用私有构造器
1 2 3 4 5 6 7 8 9 10
Class<Person> cls = Person.class; // 调用 public Person() Constructor<Person> con = cls.getConstructor(); con.newInstance(); // 调用 public Person(String name) con.newInstance("李朝"); // 调用 private Person(String name, int age) con.cls.getDeclaredConstructor(String.class, int.class); con.setAccessible(true); // 设置当前构造器为可访问 con.newInstance("李朝", 17);
意味着任何的私有变量和私有方法都可以用字节码对象来访问和调用。
使用反射调用方法
public Method[] getMethods() 获取包括自身和继承过来的所有 public 方法
public Method[] getDeclaredMethods() 获取自身类中所有的方法(不包括继承的,和访问权限无关)
public Method getMethod(String methodName, Class<?>... parameterTypes) 表示调用指定的一个公共方法(包括继承的)
public Method getDeclaredMethod(String name, Class<?>... parameterTypes) 表示调用指定的一个本类中的方法(不包括继承的)
methodName: 表示被调用方法的名字, parameterTypes: 表示调用方法的参数的 Class 类型 String.class
public Field[] getFields() // 获取所有 public 修饰的变量 public Field getField(String name)// 根据字段名获取字段 Class cls = Person.class; Field f1 = cls.getField("name"); Field f2 = cls.getDeclaredField("id"); Object obj = cls.newInstance();
@Test publicvoidtestClass()throws Exception { Class cls = Class.forName("com.lizhaoloveit._Junit.MathImpl"); Class<?>[] clss = cls.getDeclaredClasses(); for (Class<?> class1 : clss) { // 获取方法的修饰符 int mod = class1.getModifiers(); String modifier = Modifier.toString(mod); if (modifier.contains("static")) { // 构造静态成员内部类实例 Constructor con = class1.getConstructor(); Object obj = con.newInstance(); System.out.println(obj); Method m = class1.getDeclaredMethod("name"); m.setAccessible(true); m.invoke(class1); // name 方法被执行 } else { // 构造成员内部类实例 Constructor con1 = cls.getConstructor(); // 获取构造器,需要传入外部类 Class 参数 Constructor con = class1.getConstructor(cls); // 创建对象,需要外部类的构造器对象 Object obj = con.newInstance(container); System.out.println(obj); Method m = class1.getDeclaredMethod("name"); m.setAccessible(true); m.invoke(obj); } } }
System 类中,数组拷贝方法及实现
Class 类
int getModifiers() 获得修饰符
String getName() 返回类的 全限定名
Package getPackage() 获得该类的包
String getSimpleName() 获得类的简单名字
Class getSuperclass() 获得类的父类
boolean isArray() 判断该 Class 实例是否是数组
boolean isEnum() 判断该 Class 实例是否是枚举
getComponentType() Returns the Class representing the component type of an array. If this class does not represent an array class this method returns null.
返回这个 Class 代表的数组的元素类型, 如果这个 class 没有代表一个数组, 这个方法将返回 null
System 类中,数组拷贝方法
public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);