什么是反射
java反射机制: JAVA反射机制是在运行状态中,
对于任意一个类,都能够知道这个类的所有属性和方法;
对于任意一个对象,都能够调用它的任意一个方法和属性;
这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
简而言之: 就是根据一个已经实例化了的对象来还原类的完整信息
通过反射修改属性
package Test2016.demo; import java.lang.reflect.Field; public class Demo4 { public static void main(String[] args) throws Exception { Student stu = new Student(); Field[] fields = stu.getClass().getDeclaredFields(); for (Field f : fields) { f.setAccessible(true); //设置是否允许访问,不写运行会报错 if (f.getName() == "name") { f.set(stu, "java"); } else if (f.getName() == "age") { f.set(stu, 20); } } System.out.println(stu); //输出:java:20 } } class Student { private String name; private int age; public Student() { this.name = "zhangsan"; this.age = 10; } //重写toString方法,否则输出:[email protected] public String toString() { return this.name + ":" + this.age; } }
通过反射调用方法
package Test2016.demo; import java.lang.reflect.Method; public class Demo4 { @SuppressWarnings("unchecked") public static void main(String[] args) throws Exception { Student stu = new Student("zhangsan", 21); Class c = stu.getClass(); //getMethod()方法需要传入方法名和方法所带参数的参数类型 Method method = c.getMethod("score", int.class); //invoke()表示调用的意思,需要传入对象和参数 method.invoke(stu, 100); Method m = c.getMethod("say", String.class); //这里的null表示不由对象调用,也就是静态方法,把null换位stu也是可行的 m.invoke(null, "hello java!!!"); } } class Student { private String name; private int age; public Student(String name, int age) { this.name = name; this.age = age; } public void score(int score) { System.out.println(this.name + " 考了 " + score + " 分"); } public static void say(String str) { System.out.println("刚才我说了:" + str); } @Override public String toString() { return this.name + "-" + this.age; } }
程序输出: zhangsan 考了 100 分
刚才我说了:hello java!!!
通过反射操作数组
package Test2016.demo; import java.lang.reflect.Array; public class Demo4 { public static void main(String[] args) throws Exception { int[] arr = {1, 2, 3, 4, 5}; //getComponentType()返回你数组里面装的数据的数据类型的类名称。这里也就是int Class<?> c = arr.getClass().getComponentType(); System.out.println("数组类型:" + c.getName()); //数组类型:int int len = Array.getLength(arr); System.out.println("数组长度:" + len); //数组长度:5 System.out.print("遍历数组:"); for (int i = 0; i < len; i++) { System.out.print(Array.get(arr, i) + " "); //遍历数组:1 2 3 4 5 } System.out.println(); System.out.println("修改第三个数据前:" + Array.get(arr, 2)); //修改第三个数据前:3 Array.set(arr, 2, 10); System.out.println("修改第三个数据前:" + Array.get(arr, 2)); //修改第三个数据前:10 } }
注意点:
getFields()与getDeclaredFields()区别:
getFields()只能访问类中声明为公有的字段,私有的字段它无法访问,能访问从其它类继承来的公有方法.
getDeclaredFields()能访问类中所有的字段,与public,private,protect无关,不能访问从其它类继承来的方法
getMethods()与getDeclaredMethods()区别:
getMethods()只能访问类中声明为公有的方法,私有的方法它无法访问,能访问从其它类继承来的公有方法.
getDeclaredFields()能访问类中所有的字段,与public,private,protect无关,不能访问从其它类继承来的方法
getConstructors()与getDeclaredConstructors()区别:
getConstructors()只能访问类中声明为public的构造函数.
getDeclaredConstructors()能访问类中所有的构造函数,与public,private,protect无关