反射,
获取字节码文件的方式:
方式一: 对象.getClass();
方式二: 类名.Class;
方式三: Class.forName(String Class);
通过字节码文件获取对象
定义一个Student对象
package day13;public class Student { private String name; private int age; public Student() { super(); // TODO Auto-generated constructor stub } public Student(String name, int age) { super(); this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; } public void run(int a){ System.out.println("学生已经跑了"+a+"小时了......"); } }
public class FieldDemo { public static void main(String[] args) throws Exception { //获取字节码文件 Class forName = Class.forName("day13.Student");//Student为项目中的全路径 //获取对象 Object newInstance = forName.newInstance(); } }
通过字节码文件获取构造方法
public class FieldDemo { public static void main(String[] args) throws Exception { //获取字节码文件 Class forName = Class.forName("day13.Student"); //获取构造方法对象 Object newInstance = forName.newInstance(); //获取构造方法列表 Constructor[] declaredConstructors = forName.getDeclaredConstructors();//获取构造方法列表 for (Constructor constructor : declaredConstructors) { System.out.println(constructor); } Constructor constructor = forName.getConstructor();//获取空参构造 System.out.println(constructor); Constructor constructor2 = forName.getConstructor(String.class,int.class);//获取有参构造 System.out.println(constructor2); Constructor [] declaredConstructors2 = forName.getDeclaredConstructors();//获取私有和公有的构造方法列表 for (Constructor constructor3 : declaredConstructors2) { System.out.println(constructor3); } Constructor c = forName.getDeclaredConstructor(String.class,int.class);//获取所有的(私有和公有)的有参构造 System.out.println(c); Constructor c1 = forName.getDeclaredConstructor();//获取所有的(私有和公有)的无参构造 System.out.println(c1); }}
通过字节码文件和对象为字段赋值
public class FieldDemo { public static void main(String[] args) throws Exception { //获取字节码文件 Class forName = Class.forName("day13.Student"); //获取构造方法对象 Object newInstance = forName.newInstance(); //获取字段 Field age = forName.getDeclaredField("age");//获取age字段 age.setAccessible(true);//如果是私有的则需要打开开关 age.set(newInstance,15);//设置age的值为15 Field name = forName.getDeclaredField("name"); name.setAccessible(true); System.out.println(name.get(newInstance));//赋值前查看其值 name.set(newInstance,"张三"); System.out.println(name.get(newInstance));//赋值后查看其值 System.out.println(newInstance);//打印对象 }}
通过公共构造方法进行赋值
public class FieldDemo { public static void main(String[] args) throws Exception { //获取字节码文件 Class forName = Class.forName("day13.Student"); //获取构造方法对象 Object o = forName.newInstance(); //获取字段 Constructor constructor = forName.getConstructor(String.class,int.class); //通过构造方法调用对象 Object newInstance2 = constructor.newInstance("张三",15);//同过构造方法进行赋值 System.out.println(newInstance2); }}
通过私有构造方法进行赋值
public class FieldDemo { public static void main(String[] args) throws Exception { //获取字节码文件 Class forName = Class.forName("day13.Student"); //获取构造方法对象 Object o = forName.newInstance(); //获取字段 Constructor constructor = forName.getDeclaredConstructor(String.class,int.class); constructor.setAccessible(true); //通过构造方法调用对象 Object newInstance2 = constructor.newInstance("张三",15);//同过构造方法进行赋值 System.out.println(newInstance2); }}
通过方法get/Set方法进行赋值
public class FieldDemo { public static void main(String[] args) throws Exception { //获取字节码文件 Class forName = Class.forName("day13.Student"); //获取构造方法对象 Object o = forName.newInstance(); //获取字段 Method[] methods = forName.getDeclaredMethods();//获取Student中全部方法 for (Method method : methods) { //System.out.println(method); } System.out.println("------------"); //Method md = forName.getDeclaredMethod("setName"); Method md = forName.getMethod("setName",String.class);//传递参数 md.invoke(o, "张三"); Method md1 = forName.getDeclaredMethod("getName");//执行getName方法 Object name = md1.invoke(o); System.out.println(name); }}
通过字节码文件调用方法
调用Student 类中的run(int a);
public class FieldDemo { public static void main(String[] args) throws Exception { //获取字节码文件 Class forName = Class.forName("day13.Student"); //获取构造方法对象 Object o = forName.newInstance(); //参数一 方法名 参数二 参数类型对象的类 (参数列表) Method m = forName.getMethod("run",int.class); //参数一 对象 参数二 参数值(参数列表) m.invoke(o, 2); }}
通过反射可以获取类中的所有成员方,成员变量,构造方法(包括私有)。 仅仅只需要一个字符串就可以搞定了
JavaBean 对数据的封装 其实就是标准类 用于存储字段的
BeanUtils包
1.自己书写BeanUtils包
public class MyBeanUtils { public static void setProperty(Object bean, String name, Object value) {//给单个字段设置值 Class class1 = bean.getClass(); ArrayListarray=new ArrayList (); Field[] fields = class1.getFields(); for (int i = 0; i < fields.length; i++) { array.add(fields[i].getName()); } Field[] declaredFields = class1.getDeclaredFields(); for (int i = 0; i < declaredFields.length; i++) { array.add(declaredFields[i].getName()); } if (array.contains(name)) { try { Field field = class1.getDeclaredField(name); field.setAccessible(true); field.set(bean, value); } catch (Exception e) { try{ Field field = class1.getField(name); field.set(bean, value);} catch(Exception e1){ } } }else{ System.out.println("你输入的字段["+name+"]不存在!"); } } public static Object getProperty(Object bean, String name) {//获取单个属性的值 Class cs = bean.getClass(); Object object=null; try { Field field = cs.getDeclaredField(name); field.setAccessible(true); object = field.get(bean); } catch (Exception e) { } return object; } public static void populate(Object bean, Map map){//设置多个字段值 Set keys = map.keySet(); for (Object key : keys) { try{ setProperty(bean, (String) key, map.get(key)); }catch(Exception e){ } } }}