java基础之反射
package zy.refactor; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; /* * 反射:主要作用于访问一个类的私有字段和私有方法 * 使用流程1(已知类的字段以及方法): * A:获取对象Class * B:实例化对象 * C:根据字段名反射私有字段 class.getDeclaredField(字段名) * D:打开允许访问的开关 setAccessible(true); * E:赋值(set): name.set(dog, "二哈"); 访问(get): name.get(dog) * F:根据方法名反射私有方法cls.getDeclaredMethod("eat", String.class, String.class); * G:打开开关 * H:访问私有方法 m2.invoke(dog, "阿拉斯加", "全家桶"); * 使用流程2(不知道类的字段及方法): * A:获取对象Class * B:根据Class反射所有的字段名称以及类型(循环Field[]得出字段名以及字段类型) * C:根据Class反射构造方法 * D:根据构造方法创建对象(object类型) * E:根据B中得到的字段名称和类型分别定义Field并打开开关然后给私有字段赋值 Field name = cls.getDeclaredField("name"); * F:访问私有字段 * G:反射私有方法(也可以反射Method[]数组 循环得出方法名等,类似反射字段数组) * H:打开开关并访问私有方法 */ /** * 反射的应用 * * @author zy * @version 1.0 */ public class RefectorDemo { public static void main(String[] args) throws Exception { // 获取类的字节码对象(获取对象Class) 以下方法都可以 // Class cls = dog.getClass(); // Class cls = Dog.class; Class cls = Class.forName("zy.refactor.Dog"); // -------------------------------------------------------方式1 // 创建对象 Dog dog = new Dog(); // 反射私有字段 Field name = cls.getDeclaredField("name"); Field age = cls.getDeclaredField("age"); // 打开开关 name.setAccessible(true); age.setAccessible(true); // 赋值 name.set(dog, "二哈"); age.set(dog, 6); // 访问私有字段 System.out.println(name.get(dog) + "--" + age.get(dog)); // 反射私有方法 Method m1 = cls.getDeclaredMethod("eat"); Method m2 = cls.getDeclaredMethod("eat", String.class, String.class); // 打开开关 m1.setAccessible(true); m2.setAccessible(true); // 访问私有方法 m1.invoke(dog, null); m2.invoke(dog, "阿拉斯加", "全家桶"); // -----------------------------------------------------------------下面是方式2 System.out.println("----------------------------"); // 反射所有的字段名称 Field[] fields = cls.getDeclaredFields(); // 此时已经知道一共有多少字段分别为什么 可以根据字段名称以及字段类型 进行赋值 for (Field f : fields) { System.out.println(f.getType() + "--" + f.toString()); } // 此时我们已经知道Dog类中有两个私有的字段,分别为String类型的name和int类型的age;下面我们就直接用了 //反射所有方法 和反射字段基本类似 Method[] methods = cls.getDeclaredMethods(); for (Method m : methods) { System.out.println(m.getName()); } // 反射构造方法 Constructor con1 = cls.getConstructor(); Constructor con2 = cls.getConstructor(String.class, int.class); // 根据反射的构造方法创建对象 Object obj1 = con1.newInstance();// 创建对象 Object obj2 = con2.newInstance("泰迪", 3);// 创建对象并赋值 // obj1用的空构造方法 // 给obj1对象的字段赋值(因为上面循环fields已经知道了这两个字段的name和type,这里就直接赋值了) name.set(obj1, "金毛"); age.set(obj1, 4); // 访问私有字段 System.out.println(name.get(obj1) + "--" + age.get(obj1));// 金毛--4 System.out.println(name.get(obj2) + "--" + age.get(obj2));// 泰迪--3 // 访问私有方法 m1.invoke(obj1, null); m2.invoke(obj1, name.get(obj1), "金毛的食物"); m1.invoke(obj2, null); m2.invoke(obj2, name.get(obj2), "泰迪的食物"); } } package zy.refactor; /* * 反射用的dog类 */ public class Dog { private String name; private int age; public Dog() { } public Dog(String name, int age) { this.name = name; this.age = age; } private void eat() { System.out.println("狗吃骨头"); } private void eat(String name, String food) { System.out.println(name + "吃" + food); } }