反射的理解
/* * Class类对象的三种实例化模式
* 通过对象的确取得了对象的来源,这就是“反”的本质
* 在反射的世界里它再看重的不再是一个对象,而是对象身后的组成(类、构造、成员...)
*
* 取得Class类对象的好处:可以直接通过反射实例化对象:newInstance() */ public static void main(String[] args) throws ClassNotFoundException { /* * 方式一:对象名.getClass() */ Class<?> clazz=new Date().getClass(); System.out.println(clazz.getName()); System.out.println("--------------"); /* * 方式二:类名.class */ clazz= Date.class; System.out.println(clazz.getName()); /* * 方式三:Class.forName(String className) */ clazz=Class.forName("java.util.Arrays"); System.out.println(clazz.getName()); }
/*
通过反射获取普通方法,
通过反射实例化对象调用普通方法
*/
package com.reflect; import java.lang.reflect.Method; /* * * 获取方法(java.lang.Class) * getMethod(...) * getMethods() * 调用方法: * 方法对象.invoke(...) */ class Student{ private String name; public void setName(String name){ this.name=name; } public String getName(){ return name; } } /* * 需要Class类对象获取普通方法 * Method setMethod=clazz.getMethod("set"+initcap(attribute), String.class); * 需要Class类对象创建一个实例化对象来执行普通方法 * setMethod.invoke(stu, value);//相当于 stu.setName(value);此方法无返回值 */ public class Reflect_Method { public static void main(String[] args) throws Exception { Class<?> clazz=Class.forName("com.reflect.Student"); Object obj = clazz.newInstance(); String attribute="name"; String value="哈哈"; //获取setName()方法,根据"set"+属性进行拼接的 Method setMethod=clazz.getMethod("set"+initcap(attribute), String.class); setMethod.invoke(obj, value);//相当于 stu.setName(value);此方法无返回值 //获取getName()方法 Method getMethod=clazz.getMethod("get"+initcap(attribute)); Object obj1=getMethod.invoke(obj);//相当于 stu.getName();此方法有返回值 System.out.println(obj1); } public static String initcap(String s){ return s.substring(0,1).toUpperCase().concat(s.substring(1)); } }
/*
反射操作字段
*/
package com.reflect; import java.lang.reflect.AccessibleObject; import java.lang.reflect.Field; /* * 反射调用成员(字段/属性) * getFileds():获取父类的所有成员 * getDeclaredFields():获取本类的所有成员 * * 设置成员值 * 成员对象.set(obj,value) * 获取成员值 * 成员对象.get(obj) * 获取成员类型 * 成员对象.getType() (比较重要) */ class People{ //public String name; private String name; } class Teacher extends People{ private String teacher; } public class Reflect_Field { public static void main(String[] args) throws Exception{ //获取Class类对象 Class<?> clazz = Class.forName("com.reflect.Teacher"); //要使用字段,必须先实例化对象 Object obj = clazz.newInstance(); //获取指定字段 Field field = clazz.getDeclaredField("teacher"); field.setAccessible(true);//取消了封装(AccessibleObject) field.set(obj,"张三");//相当于 设置(对象.teacher="张三"); Object obj1=field.get(obj);//相当于 获取(对象.teacher); System.out.println(obj1); } }
/* 通过遍历字段,获取字段对应的方法 方法:是由set/get 和字段名 拼接而成的
注意:
采用setter设置值时,不用设置 字段对象.setAccessible(true); */ Class<?> clazz=Class.forName("com.mldn.reflect.Grade"); //实例化对象 Object obj = clazz.newInstance(); Field[] fields = clazz.getDeclaredFields(); //遍历字段数组 for(Field f:fields){ String fieldName = f.getName(); //获取对应属性的方法(由set/get+属性拼接而成的) Method setMethod= clazz.getMethod("set"+initCap(fieldName), f.getType()); if(f.getType()==int.class){ setMethod.invoke(obj,98);// 对象.setScore(98); } if(f.getType()==String.class){ setMethod.invoke(obj,"数学"); } Method getMethod=clazz.getMethod("get"+initCap(fieldName)); Object obj1= getMethod.invoke(obj);// 对象.getScore(); System.out.println(obj); }