Java学习之反射
Java 反射机制是在运行状态中,对于任意一个类(class文件),都能够知道这个类的所有属性和方法。
对于任意一个对象,都能够调用它的任意一个方法和属性
反射实际要做的动作
1、加载指定的class文件,并创建Class对象
2、实例化对象
3、通过实例化对象获取字段对象,并对字段对象的设置和获取
4、通过实例化对象获取方法对象,并对方法进行调用
一、加载指定的class文件,并创建Class对象
有三种方式
1 /* 2 * 获取字节码对象的方式三、 3 * 根据类的全名称获取该类 4 */ 5 public static void forNameObject() throws ClassNotFoundException { 6 String className="cn.marw.bean.Person"; 7 Class clazzClass=Class.forName(className); 8 } 9 10 /* 11 * 获取字节码对象的方式二、 12 * 任何数据类型都具备一个静态的属性.class来获取其对象的class对象 13 * 必须明确类 14 */ 15 public static void classObject() { 16 Class clazzClass=Person.class; 17 } 18 19 /* 20 * 获取字节码对象的方式一 21 * Object类中的getClass方法 22 * 必须明确具体的类,并创建对象 23 */ 24 public static void getClassObject() { 25 Person p=new Person(); 26 Class clazzClass=p.getClass(); 27 Person p1=new Person(); 28 Class clazzClass1=p1.getClass(); 29 }
二、实例化对象
有两种方式:
1 /* 2 * 方式二、 3 * 有参构造函数实例化 4 */ 5 public static void createParamNewObject() throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException { 6 7 //cn.marw.bean.Person p = new cn.marw.bean.Person("小明",29); 8 9 //相当于以下代码 10 String className="cn.marw.bean.Person"; 11 Class clazzClass=Class.forName(className); 12 /* 13 * 获取构造函数对象 14 * 15 * 所有公共构造函数 16 * getConstructor(); 17 * 获取所有访问权限(public、private)的构造函数(Declared:无视访问权限) 18 * getDeclaredConstructor(); 19 * 20 * 获取指定公共(public)构造函数,因为构造函数名都时一样的,所以只需要查看构造函数的参数列表的类型22 * getConstructor(parameterTypes); 23 * getDeclaredConstructor(parameterTypes); 24 * 25 * parameterTypes:构造函数的参数列表中参数类型对应的字节码对象27 * 如:String => String.class 28 */ 29 Constructor constructor=clazzClass.getConstructor(String.class,int.class); 30 31 /* 32 * 通过该构造器对象的newInstance方法进行对象的初始化 33 */ 34 Object object=constructor.newInstance("小明",29); 35 } 36 /* 37 * 方式一、 38 * 无参构造函数实例化 39 */ 40 public static void createNewObject() throws Exception { 41 // 42 cn.marw.bean.Person p = new cn.marw.bean.Person(); 43 //相当于以下代码 44 String className="cn.marw.bean.Person"; 45 Class clazzClass=Class.forName(className); 46 /* 47 * newInstance():创建此Class对象所表示的类的一个新实例。如同一个带有空参列表的实例化 48 * 如果没有Person类没有空参构造函数时,InstantiationException 49 */ 50 Object obj = clazzClass.newInstance(); 51 }
三、对象字段
1 private static void getFieldDemo() throws Exception { 2 Class clazz=Class.forName("cn.marw.bean.Person"); 3 //只能获取共有的字段,包含父类的共有字段 4 //Field field=clazz.getField("age"); 5 //只能获取本类所有字段 6 field = clazz.getDeclaredField("age"); 7 /* 8 * 对私有字段的访问取消权限检查。暴力访问 9 */ 10 field.setAccessible(true); 11 /* 12 * cn.marw.bean.Person person= new cn.marw.bean.Person(); 13 * person.age=30; 14 * 访问字段必须是对象 15 * field.get(Object);//指定字段所属的对象 16 */ 17 Object object=clazz.newInstance(); 18 field.set(object, 28); 19 field.get(object); 20 }
四、对象函数
1 private static void getMethodDemo() throws Exception { 2 Class clazz = Class.forName("cn.marw.bean.Person"); 3 /* 4 * 获取共有的方法,包括父类 5 */ 6 Method[] methods = clazz.getMethods(); 7 8 /* 9 * 获取本类所有方法,不包含父类 10 */ 11 methods = clazz.getDeclaredMethods(); 12 for (Method method : methods) { 13 System.out.println(method); 14 } 15 /* 16 * 获取对象 17 */ 18 Constructor constructor = clazz.getConstructor(String.class,int.class); 19 Object obj = constructor.newInstance("小明",25); 20 /* 21 * 获取指定方法 22 */ 23 Method method = clazz.getMethod("show",null); 24 /* 25 * 函数调用 26 */ 27 method.invoke(obj, null); 28 29 /* 30 * 获取对象 31 */ 32 obj=clazz.newInstance(); 33 /* 34 * 获取指定有参函数 35 * 1、指定方法名 36 * 2、参数列表类型对应的字节码对象 37 */ 38 method = clazz.getMethod("paramMethod",String.class,int.class); 39 /* 40 * 函数调用 41 * 1、函数所属对象 42 * 2、参数列表对应内容 43 */ 44 method.invoke(obj, "小强",22); 45 }