概念:什么是反射
java反射机制: JAVA反射机制是在运行状态中,
对于任意一个类,都能够知道这个类的所有属性和方法;
对于任意一个对象,都能够调用它的任意一个方法和属性;
这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
简而言之: 就是根据一个已经实例化了的对象来还原类的完整信息
案例1:通过反射修改属性
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方法,否则输出:Test2016.demo.Student@e53108
public String toString() {
return this.name + ":" + this.age;
}
}
案例2:通过反射调用方法
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!!!
案例3:通过反射操作数组
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无关