反射介绍第二弹。

Java反射(Reflection)(二)

  • 获取了某个Object实例对应的Class,我们就可以通过反射获取他的一切信息。

1. 访问字段(Filed)

  • 通过Class访问字段(Field)信息的几个方法

    • Field getField(String name) :获取指定名称的Field(包含父类,子类的public的Field)

    • Filed getDeclaredField(String name) :获取指定名称的Filed(包含子类的所有Field)

    • Field[] getFields() :获取所有Field(包含父类,子类的public的Field)

    • Filed[] getDeclaredFields() :获取所有Filed(包含子类的所有Field)

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      package top.tobing.reflection;
      import java.lang.reflect.Field;
      /**
      * 获取实例的字段信息
      * @author Tobing
      */
      public class Demo02ReflectField {
      public static void main(String[] args) throws NoSuchFieldException, SecurityException {
      Student stu = new Student();
      // 获取Student名称为id的Field
      System.out.println(stu.getClass().getField("name"));
      System.out.println(stu.getClass().getField("id"));
      System.out.println(stu.getClass().getDeclaredField("score"));
      // 以下语句会抛出:java.lang.NoSuchFieldException 该方法不能找到父类的public方法
      //System.out.println(stu.getClass().getDeclaredField("name"));
      Field[] fields1 = stu.getClass().getFields(); // 获取stu的使用public修饰的方法
      System.out.println("stu的public修饰Field(包含父类):");
      for(Field f:fields1) {
      System.out.println(f.getName());
      }
      Field[] fields2 = stu.getClass().getDeclaredFields();
      System.out.println("本类中的所有属性(包含private):");
      for(Field f:fields2) {
      System.out.println(f.getName());
      }

      }
      }

      class Human{
      public String name;
      }

      class Student extends Human {
      public String id;
      private double score;
      }
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      # 输出结果
      public java.lang.String top.tobing.reflection.Human.name
      public java.lang.String top.tobing.reflection.Student.id
      private double top.tobing.reflection.Student.score
      stu的public修饰Field(包含父类):
      id
      name
      本类中的所有属性(包含private):
      id
      score
  • Field的常用操作

    • String getName()
            返回此 Field 对象表示的字段的`名称 `
    • Class<?> getType()
            返回一个 Class 对象,它标识了此 Field 对象所表示字段的`声明类型`。 
    • int getModifiers()
            以整数形式返回由此 Field 对象表示的字段的` Java 语言修饰符`。 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    package top.tobing.reflection;
    import java.lang.reflect.Field;
    import java.lang.reflect.Modifier;
    /**
    * 字段的常用方法
    * @author Tobing
    */
    public class Demo03ReflectField2 {
    public static void main(String[] args) throws NoSuchFieldException, SecurityException {
    Teacher t = new Teacher();
    Field f2 = t.getClass().getDeclaredField("age");
    Field f1 = t.getClass().getDeclaredField("name");
    System.out.println("-----------------------------------------------------");
    System.out.println("名称:"+f1.getName());
    System.out.println("返回值类型:"+f1.getType());
    System.out.println("Java语言修饰符int形式:"+f1.getModifiers());
    System.out.println("isPrivate:"+Modifier.isPrivate(f1.getModifiers()));

    System.out.println("-----------------------------------------------------");
    System.out.println("名称:"+f2.getName());
    System.out.println("返回值类型:"+f2.getType());
    System.out.println("Java语言修饰符int形式:"+f2.getModifiers());
    System.out.println("isPublic:"+Modifier.isPublic(f2.getModifiers()));
    }
    }
    class Teacher{
    private String name;
    public int age;
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # 输出结果
    -----------------------------------------------------
    名称:name
    返回值类型:class java.lang.String
    Java语言修饰符int形式:2
    isPrivate:true
    -----------------------------------------------------
    名称:age
    返回值类型:int
    Java语言修饰符int形式:1
    isPublic:true

2. 访问字段的值

  • Object get(Object obj) :返回指定实例对应字段的值

    Returns the value of the field represented by this Field, on the specified object. 
  • void setAccessible(boolean flag) :设置是否可以范围(权限不够的时候)

    ​ Set the accessible flag for this object to the indicated boolean value.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    package top.tobing.reflection;
    import java.lang.reflect.Field;
    import java.lang.reflect.Modifier;
    /**
    * 字段的常用方法
    * @author Tobing
    */
    public class Demo03ReflectField3 {
    public static void main(String[] args) throws Exception{
    People p = new People();
    p.setName("张三丰");
    Field f1 = p.getClass().getDeclaredField("name");
    // f1.get(p); //直接执行该语句会抛出异常java.lang.IllegalAccessException
    // cannot access a member of class top.tobing.reflection.People with modifiers "private"
    //不能访问修饰符为private的字段
    // 暴力反射,忽略修饰符 // 通常情况下,如果修饰符权限不够就考虑使用该方法(反射是非常规的用法)
    f1.setAccessible(true);
    Object obj = f1.get(p);
    System.out.println(obj); // 输出: 张三丰
    f1.set(p,"张无忌");
    System.out.println(f1.get(p)); // 修改后输出 张无忌
    }
    }
    class People{
    private String name;
    public int age;
    public void setName(String name) {
    this.name = name;
    }
    }

总结

  • 理解还未深入,仍需学习。

评论