day44-反射03( 三 )


day44-反射03

文章插图
5.通过反射访问类中的成员
  • 访问属性
    1. 根据属性名获取Field对象
      Field f = class对象.getDeclaredField(属性名);
    2. 爆破:f.setAccessible(true);//f是Field
    3. 访问
      f.set(o,值);//o表示对象
      syso(f.get(o));//o表示对象
    4. 注意:如果是静态属性,则set和get中的参数o , 可以写为null
例子:
package li.reflection;import java.lang.reflect.Field;//演示反射操作属性Fieldpublic class ReflectAccessProperty {public static void main(String[] args) throws Exception {//1.得到Student类对应的Class对象Class<?> stuClass = Class.forName("li.reflection.Student");//2.创建对象Object o = stuClass.newInstance();//o的运行类型就是StudentSystem.out.println(o.getClass());//Student//3.使用反射得到age属性对象(公有)Field age = stuClass.getField("age");age.set(o,88);//通过反射来操作属性System.out.println(o);//Student [age=88, name = null]//或者System.out.println(age.get(o));//返回age属性的值 88//4.使用反射操作name属性(私有静态的属性)Field name = stuClass.getDeclaredField("name");//因为name是私有的属性 , 需要对 name进行爆破name.setAccessible(true);name.set(o,"jack");//也可以写name.set(null,"jack");因为name是静态属性,与类有关,与对象无关System.out.println(o);System.out.println(name.get(o));//jack}}class Student {public int age;private static String name;public Student() {}@Overridepublic String toString() {return "Student [age=" + age + ", name = " + name + "]";}}
day44-反射03

文章插图
  • 访问方法
    1. 根据方法名和参数列表获取Method方法对象:
      Method m = 类的Class对象.getDeclaredMethod(方法名,XX.class);//得到本类的所有方法
      XX.class指方法的参数对应的class
    2. 获取对象:Object o = 类的Class对象.newInstance();
    3. 爆破:m.setAccessible(true);
    4. 访问:Object returnValue = https://www.huyubaike.com/biancheng/m.invoke(o,实参列表);
    5. 注意:如果过是静态方法 , 则invoke的参数o可以写为null
例子:
package li.reflection;import java.lang.reflect.Method;//演示通过反射操作方法public class ReflectAccessMethod {public static void main(String[] args) throws Exception {//1.得到Boss类对应的Class对象Class<?> bossCls = Class.forName("li.reflection.Boss");//2.创建对象Object o = bossCls.newInstance();//3.调用普通的public的hi方法//3.1得到hi方法对应的方法对象Method hi = bossCls.getMethod("hi", String.class);//3.2调用hi.invoke(o, "孙悟空");//4.调用private static 方法//注意点:1.private:要使用爆破;2.static:在invoke时的参数可以写null//4.1得到 say 方法对象Method say = bossCls.getDeclaredMethod("say", int.class, String.class, char.class);//4.2爆破say.setAccessible(true);//4.3invoke的nullSystem.out.println(say.invoke(o, 100, "张三", '男'));System.out.println(say.invoke(null, 999, "李四", '女'));//因为是静态的方法,所以o可以写为null//5.在反射中 , 如果方法有返回值,统一返回Object,但其运行类型和方法定义的返回类型一致Object reVal = say.invoke(null, 300, "jack", '男');System.out.println("reVal的运行类型=" + reVal.getClass());//String}}class Boss {public int age;private static String name;public Boss() {}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);}}
day44-反射03

文章插图
6.本章作业6.1练习1:通过反射修改私有成员变量
  1. 定义privateTest类 , 有私有属性name,并且属性值为"hellokitty"
  2. 提供getName的公有方法
  3. 创建PrivateTest的类,利用Class类的到私有属性name , 修改其属性值,并调用getName()的方法打印name属性值
package li.reflection.homework;import java.lang.reflect.Field;import java.lang.reflect.Method;public class homework01 {public static void main(String[] args) throws Exception {//1.得到PrivateTest对应的Class对象Class<?> privateTestCls = Class.forName("li.reflection.homework.PrivateTest");//2.创建对象Object o = privateTestCls.newInstance();//3.得到name属性对象Field name = privateTestCls.getDeclaredField("name");//4.爆破name.setAccessible(true);name.set(o,"天龙八部");//5.得到getName方法的对象Method method = privateTestCls.getMethod("getName");//6.因为getName是public方法,直接调用即可Object invoke = method.invoke(o);System.out.println("name属性的值="+invoke);}}class PrivateTest{private String name = "HelloKitty";public String getName(){return name;}}

推荐阅读