目录
Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。反射被视为动态语言的关键。
Class.forName(完整类名)、类名.class、对象.getClass
编写一个student类
- package com.zking.reflect;
-
- public class Student {
- private String sid;
-
- private String sname;
-
- public Integer age;
-
- static {
- System.out.println("加载进jvm中!");
- }
-
- public Student() {
- super();
- System.out.println("调用无参构造方法创建了一个学生对象");
- }
-
- public Student(String sid) {
- super();
- this.sid = sid;
- System.out.println("调用带一个参数的构造方法创建了一个学生对象");
- }
-
- public Student(String sid, String sname) {
- super();
- this.sid = sid;
- this.sname = sname;
- System.out.println("调用带二个参数的构造方法创建了一个学生对象");
- }
-
- @SuppressWarnings("unused")
- private Student(Integer age) {
- System.out.println("调用Student类私有的构造方法创建一个学生对象");
- this.age = age;
- }
-
- public String getSid() {
- return sid;
- }
-
- public void setSid(String sid) {
- this.sid = sid;
- }
-
- public String getSname() {
- return sname;
- }
-
- public void setSname(String sname) {
- this.sname = sname;
- }
-
- public void hello() {
- System.out.println("你好!我是" + this.sname);
- }
-
- public void hello(String name) {
- System.out.println(name + "你好!我是" + this.sname);
- }
-
- @SuppressWarnings("unused")
- private Integer add(Integer a, Integer b) {
- return new Integer(a.intValue() + b.intValue());
- }
- }
使用三种类类方法测试
- public class Demo {
-
- public static void main(String[] args) throws Exception {
-
- // 1、Class.forName
- Class> class1 = Class.forName("com.zking.reflect.Student");
-
- // 2、类.class
- Class> class2 = Student.class;
-
- // 3、对象.class
- Student stu = new Student();
- Class> class3 = stu.getClass();
- System.out.println(class1);
- System.out.println(class2);
- System.out.println(class3);
- }
-
- }
运行结果如下:
三种实例化方法:getConstructor、getDeclaredConstructor、newlnstance
// 1、Class.forName Class> class1 = Class.forName("com.zking.reflect.Student"); // 2、类.class Class> class2 = Student.class; Constructor> cs=class1.getConstructor(); Student stu1 = (Student) class1.newInstance(); stu1.setSname("zs"); System.out.println(stu1);强制转换的话要使用泛型
// 1、Class.forName Classclass1 = (Class ) Class.forName("com.zking.reflect.Student"); // 2、类.class Class> class2 = Student.class; //无参数 Constructor> cs=class1.getConstructor(); Student stu1 = cs.newInstance(); stu1.setSname("zs"); System.out.println(stu1); //有一个参数 Constructorcs1 = class1.getConstructor(String.class); Student stu2 = cs1.newInstance("0001"); stu2.setSname("ww"); System.out.println(stu2); //有两个参数 Constructorcs2 = class1.getConstructor(String.class,String.class); Student stu3 = cs2.newInstance("0001","ls"); System.out.println(stu3); Constructorcs3=class1.getDeclaredConstructor(Integer.class); cs3.setAccessible(true);//暴力反射 既可以获取私有方法也可以获取公有方法 Student stu4 = cs3.newInstance(23); System.out.println(stu4);结果如下:
getMethod、getDeclaredMethod
Method method1 = class1.getMethod("hello"); stu4.setSname("zs"); method1.invoke(stu4);//invoke 调用Method类的方法,可以实现动态调用 System.out.println("-------------"); Method method2 = class1.getMethod("hello", String.class); method2.invoke(stu4, "ww"); System.out.println("-------------"); Method method3 = class1.getDeclaredMethod("add", Integer.class, Integer.class); method3.setAccessible(true);//会出现不合法访问异常,这时候用暴力反射 int a = (int) method3.invoke(stu4, 1, 2); System.out.println("add 1,2=" + a);效果如下:
getDeclaredField、getDeclaredFields
Field field1 = class1.getField("age");//通过字符串获取属性 field1.set(stu4, 70); System.out.println(stu4); Field field2 = class1.getDeclaredField("sname"); field2.setAccessible(true); field2.set(stu4, "lhl"); System.out.println(stu4);效果如下:
Field[] field3 = class1.getDeclaredFields(); // 通过循环数值完成动态赋值 for (Field field : field3) { field.setAccessible(true); System.out.println(field.get(class1.newInstance())); }