1、访问属性

a.根据属性名获取Field对象

Field f = clazz对象.getDeclaredField(属性名);

b.暴破:f.setAccessible(true); //f是Field

c.访问

f.set(o,值); //o表示对象

d.注意:如果是静态属性,则set和get中的参数o,可以写成null。

package com.test;
class Student {
    public int age;
    private static String name;
    public Student() { // 构造器
    }
    public String toString() {
        return "Student [age=" + age + ", name=" + name + "]";
    } 
}

package com.test;
public class ReflecAccessProperty {
    public static void main(String[] args) throws Exception {
//      1.得到 Student 类对应的 Class 对象
        Class<?> stuClass = Class.forName("com.test.Student");
//        2.创建对象
        Object o = stuClass.newInstance();
        System.out.println(o.getClass());// o 的运行类型是Student
//        3.使用反射得到 age 属性对象
        Field age = stuClass.getField("age");
        age.set(o, 88);//通过反射来操作属性
        System.out.println(o);
        System.out.println(age.get(o));//返回 age 属性的值
//        4.使用反射操作 name 属性
        Field name = stuClass.getDeclaredField("name");
//        对name进行暴破,可以操作 private 属性
        name.setAccessible(true);
//        name.set(o,"张三丰");
        name.set(null, "秦始皇");//因为name 是 static 属性,因此 o 也可以写成null
        System.out.println(o);
        System.out.println(name.get(o));//获取属性值
        System.out.println(name.get(null));//获取属性值,要求name是static
    } 
}

2、访问方法

a.根据方法名和参数列表获取Method方法对象

Method m = clazz.getDeclaredMethod(方法名,XX.class); //得到本类的所有方法

b.获取对象:Object o = clazz.newInstance();

c.暴破:m.setAccessible(true);

d.访问:Object returnValue = m.invoke(o,实参列表); //o就是对象

e.注意:如果是静态方法,则invoke的参数o,可以写成null。

package com.test;
class Monster {
}
package com.test;
class Boss {
    public int age;
    private static String name;
    public Boss() {//构造器
    }
    public Monster m1() {
        return new Monster();
    }
    private static String say(int n, String s, char c) {//静态方法
        return n + " " + s + " " + c;
    }
    public void hi(String s) {//普通 public 方法
        System.out.println("hi" + s);
    } 
}
package com.test;

public class ReflecAccessMethod {
    public static void main(String[] args) throws Exception {
//        1.得到Boss类对应的Class对象
        Class<?> bossClass = Class.forName("com.test.Boss");
//        2.创建对象
        Object o = bossClass.newInstance();
//        3.调用 public 的hi方法
//        3.1 得到hi方法对象
        Method hi = bossClass.getDeclaredMethod("hi", String.class);
//        3.2 调用
        hi.invoke(o,"我在学Java");
//        4.调用 private static 方法
//        4.1 得到 say 方法对象
        Method say = bossClass.getDeclaredMethod("say", int.class, String.class, char.class);
//        4.2 因为 say 方法是private,所以需要暴破
        say.setAccessible(true);
        System.out.println(say.invoke(o,100,"张三",'男'));
//        4.3 因为say方法是static的,还可以这样调用,可以传入 null
        System.out.println(say.invoke(null,200,"李四",'女'));
//        5.在反射中,如果方法有返回值,统一返回Objec,但是它的运行类型和方法定义的返回类型一致
        Object reVal = say.invoke(null, 300, "王五", '男');
        System.out.println("reVal的运行类型="+reVal.getClass());
    } 
}