Java反射学习(3)(“反射“机制获取成员变量及详细信息(Field类))

目录

一、基本引言。

(1)基本内容回顾。

(2)本篇博客的核心内容-基本介绍。

二、Java中使用"反射"机制获取成员变量及内部的详细信息。

(1)"反射"机制获取成员变量及详细信息的基本概念。

(2)利用Java的对象机制进行封装。(Field类)

1、构造方法。(Constructor类)

2、字段(成员变量)。(Field类)

3、成员方法。(Method类)

(3)操作成员变量(字段)的类"Field"相关的操作方法。

1、Class类中用于获取成员变量(字段)(返回Field类对象)的常用方法。

2、Field类中用于创建对象的方法。

3、Field类对象的重要且常用的操作方法。

(4)有关"Field"类的核心方法的操作演示。

<1>第一步。获取对应Student类的字节码文件对象(Class类)。

<2>第二步。通过Class对象获取Student类中对应成员变量(字段)"Field"对象。

<3>第三步。通过获取的成员变量(字段)"Field"对象获取其内部详细信息。


一、基本引言。

(1)基本内容回顾。

(2)本篇博客的核心内容-基本介绍。
  • 本篇博客的内容围绕:通过"反射"机制(.class字节码文件——>Class类对象)获取成员变量及详细信息——>Field类的相关操作。
  • 原理图如下所示。

二、Java中使用"反射"机制获取成员变量及内部的详细信息。

(1)"反射"机制获取成员变量及详细信息的基本概念。
  • 在Java中,反射是一种强大的机制,它允许程序在运行时访问、检查和修改它自己的结构,比如类、接口、字段和方法。合理使用"反射"特性,可以获取成员变量(字段)及其详细信息。

  • 在介绍如何使用"反射"来获取类中(.class字节码文件)的成员变量及其详细信息的基本步骤之前需要先了解类"Field"。

(2)利用Java的对象机制进行封装。(Field类)
  • 基于"Java万事万物皆对象"的机制。
  • 使用.class(字节码文件)——(字节码文件对象)"Class"类对象获取对应类的信息。

1、构造方法。(Constructor类)
  • 封装构造方法的实体类"Constructor"。(在引言中已经提及)

2、字段(成员变量)。(Field类)
  • 封装成员变量的实体类"Field"。(本篇博客讨论的重点)

3、成员方法。(Method类)
  • 封装成员方法的实体类"Method"。(后面博客讨论学习)

(3)操作成员变量(字段)的类"Field"相关的操作方法。
1、Class类中用于获取成员变量(字段)(返回Field类对象)的常用方法。
  • 简单识别法:带"s"的获取的值不只一个带"declared"无视访问修饰符权限全部拿到
方法声明功能描述
Field [] getFields();返回所有公共成员变量对象的数组
Field [] getDeclaredFields();返回所有成员变量对象的数组。(包括私有成员变量)
Field getField(String name);

返回单个公共成员变量对象


(获取到成员变量对象:进行"解剖"——>获取权限修饰符、数据类型、存储的值都能够获取到!)

Field getDeclaredField(Stringname);返回单个成员变量对象
2、Field类中用于创建对象的方法。
方法声明功能描述
void set(Object obj,Object value);给成员变量(字段)赋值
Object get(Object obj);获取成员变量(字段)的值
3、Field类对象的重要且常用的操作方法。
方法声明功能描述
getModifiers();获取属性的权限修饰符
getName();获取属性的名称
isAccessible();判断属性是否可被外部访问
setAccessible(Boolean flag);设置属性是否可被外部访问
toString();返回Field类的信息
(4)有关"Field"类的核心方法的操作演示。
  • 提供一个实体类:Student。
  • Student类提供三个成员变量。提供正常的构造方法、getter与setter方法。
  • 访问权限为private成员变量name
  • 访问权限为private的成员变量age
  • 访问权限为public的成员变量gender
package com.fs.entity;

public class Student {
    //提供成员变量
    private String name;
    private int age;
    public String gender;

    //无参构造(访问权限:public)
    public Student() {
    }

    //有参构造(访问权限:public)
    public Student(String name, int age, String gender) {
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    //提供对于成员属性的getter、setter方法

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    //提供toString方法
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", gender='" + gender + '\'' +
                '}';
    }
}

  • 最后会提供一个测试类(Main类)进行核心方法操作的测试。

<1>第一步。获取对应Student类的字节码文件对象(Class类)。
package com.fs.test;

public class Main {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
        //1.通过Student类的全限定类名获取class字节码文件对象
        Class<?> clazz = Class.forName("com.fs.entity.Student");
    }
}
<2>第二步。通过Class对象获取Student类中对应成员变量(字段)"Field"对象。
  • 通过字节码文件对象(Class对象)获取所有公共的(public)成员变量。
package com.fs.test;
import com.fs.entity.Student;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;


public class Main {
    public static void main(String[] args) throws ClassNotFoundException{
        //1.通过Student类的全限定类名获取class字节码文件对象
        Class<?> clazz = Class.forName("com.fs.entity.Student");

        //通过字节码文件对象获取所有公共(public)的成员变量对象
        Field[] fields = clazz.getFields();
        for (Field field : fields) {
            System.out.println(field);
        }
    }
}

  • 通过字节码文件对象(Class对象)获取所有成员变量。(包括private修饰的字段)

package com.fs.test;
import java.lang.reflect.Field;

public class Main {
    public static void main(String[] args) throws ClassNotFoundException{
        //1.通过Student类的全限定类名获取class字节码文件对象
        Class<?> clazz = Class.forName("com.fs.entity.Student");

        //通过字节码文件对象获取所有的成员变量对象
        Field[] declaredFields = clazz.getDeclaredFields();
        for (Field field : declaredFields) {
            System.out.println(field);
        }

    }
}


  • 获取单个成员变量。(public修饰的)
package com.fs.test;
import java.lang.reflect.Field;

public class Main {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        //1.通过Student类的全限定类名获取class字节码文件对象
        Class<?> clazz = Class.forName("com.fs.entity.Student");

        //获取单个成员变量(public gender)对象
        Field gender = clazz.getField("gender");
        System.out.println(gender);

    }
}


  • 获取单个成员变量。(private修饰的)
package com.fs.test;
import java.lang.reflect.Field;

public class Main {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        //1.通过Student类的全限定类名获取class字节码文件对象
        Class<?> clazz = Class.forName("com.fs.entity.Student");

        //获取单个成员变量(private name)对象
        Field name = clazz.getDeclaredField("name");
        System.out.println(name);


    }
}


<3>第三步。通过获取的成员变量(字段)"Field"对象获取其内部详细信息。
  • 获取成员变量的访问权限修饰符。
package com.fs.test;
import java.lang.reflect.Field;

public class Main {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        //1.通过Student类的全限定类名获取class字节码文件对象
        Class<?> clazz = Class.forName("com.fs.entity.Student");

        //获取单个成员变量(private name)对象
        Field name = clazz.getDeclaredField("name");
        System.out.println(name);

        //获取成员变量的访问修饰符
        int modifiers = name.getModifiers();
        System.out.println(modifiers);


    }
}



  • 获取成员变量的对应名称。
package com.fs.test;
import java.lang.reflect.Field;

public class Main {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        //1.通过Student类的全限定类名获取class字节码文件对象
        Class<?> clazz = Class.forName("com.fs.entity.Student");

        //获取单个成员变量(private name)对象
        Field nameField = clazz.getDeclaredField("name");
        System.out.println(nameField);

        //获取成员变量的名称
        String name = nameField.getName();
        System.out.println(name);


    }
}


  • 获取成员变量的对应参数数据类型。
package com.fs.test;
import java.lang.reflect.Field;

public class Main {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        //1.通过Student类的全限定类名获取class字节码文件对象
        Class<?> clazz = Class.forName("com.fs.entity.Student");

        //获取单个成员变量(private name)对象
        Field nameField = clazz.getDeclaredField("name");
        System.out.println(nameField);

        //获取成员变量的参数的数据类型
        Class<?> type = nameField.getType();
        System.out.println(type);
        
    }
}


  • 获取对应成员变量对象的值。
  • 前提得创建(拥有)一个Student类的对象。
  • 调用“Field”类对象的get()方法。传入值:Student类的对象即可。


  • 通过方法setAccessible(Boolean flag)"强行关闭权限校验"拿取对应的属性值。
package com.fs.test;
import com.fs.entity.Student;

import java.lang.reflect.Field;

public class Main {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
        //1.通过Student类的全限定类名获取class字节码文件对象
        Class<?> clazz = Class.forName("com.fs.entity.Student");

        //获取单个成员变量(private name)对象
        Field nameField = clazz.getDeclaredField("name");
        System.out.println(nameField);

        //获取成员变量对应的值
        //前提:从创建的对象中获取成员变量的值
        //创建一个Student类对象
        Student s = new Student("张三", 23, "男");
        //临时取消访问权限检查
        nameField.setAccessible(true);
        //获取对应的name属性值
        String value = (String) nameField.get(s);
        System.out.println(value);

    }
}


  • 修改成员变量(字段)对象里面存储的值。
  • 使用set(Objetc obj,Object Value)方法即可。
package com.fs.test;
import com.fs.entity.Student;

import java.lang.reflect.Field;

public class Main {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
        //1.通过Student类的全限定类名获取class字节码文件对象
        Class<?> clazz = Class.forName("com.fs.entity.Student");

        //获取单个成员变量(private name)对象
        Field nameField = clazz.getDeclaredField("name");
        System.out.println(nameField);

        //获取成员变量对应的值
        //前提:从创建的对象中获取成员变量的值
        //创建一个Student类对象
        Student s = new Student("张三", 23, "男");
        //临时取消访问权限检查
        nameField.setAccessible(true);
        //获取对应的name属性值
        String value = (String) nameField.get(s);
        System.out.println(value);

        //修改字段对象(Field)的指定字段值
        //第一个参数:需要修改的对象,第二个参数:需修改的值
        nameField.set(s, "李四");
        System.out.println(s);

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

岁岁岁平安

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值