Java----反射

什么是反射?

反射就是允许对成员变量、成员方法和构造方法的信息进行编程访问。换句话来讲,就是通过反射,我们可以在不需要创建其对象的情况下就可以获取其定义的各种属性值以及方法。常见的应用就是IDEA中的提示功能,当我们使用某个对象,使用"."的时候,IDEA会自动进行提示,会弹出一个显示关于该对象所有能调用的方法。

想要使用反射,首先要先创建某个对象的字节码对象,常见的创建方式有以下几种,(第一种的地址可以在IDEA中使用右键复制其引用):

代码编写

这里我们采用第一种进行创建:

复制代码
package com.wxy.instance;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;

public class ClassTest {
    public static void main(String[] args) throws ClassNotFoundException, InvocationTargetException, InstantiationException, IllegalAccessException {
        //获得字节码对象
        Class<?> clazz = Class.forName("com.wxy.instance.Student");
        
        //调用获取构造列表,并选择其中的第3个
        Constructor<?>[] declaredConstructors = clazz.getDeclaredConstructors();
        System.out.println(Arrays.toString(declaredConstructors));

        Constructor<?> declaredConstructor = declaredConstructors[2];
        
        //由于我的对象中第3个构造方法是private修饰,不允许外部调用,所以我们需要使用调用下面的方法,临时取消权限的校验
        declaredConstructor.setAccessible(true);

        //通过获得的构造方法使用newInstance()可以创建对象
        Student xiaoming = (Student) declaredConstructor.newInstance("xiaoming");
        System.out.println(xiaoming);
    }
}

以下是示例对象:

复制代码
package com.wxy.instance;

public class Student {
    private Integer id;
    private String name;
    private Integer age;


    public Student() {
    }

    private Student(String name) {
        this.name = name;
    }

    private Student(Integer id, String name, Integer age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    /**
     * 获取
     * @return id
     */
    public Integer getId() {
        return id;
    }

    /**
     * 设置
     * @param id
     */
    public void setId(Integer id) {
        this.id = id;
    }

    /**
     * 获取
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     * @return age
     */
    public Integer getAge() {
        return age;
    }

    /**
     * 设置
     * @param age
     */
    public void setAge(Integer age) {
        this.age = age;
    }

    public String toString() {
        return "Student{id = " + id + ", name = " + name + ", age = " + age + "}";
    }

    /**
     * 测试反射获取成员方法
     * @param arg
     */
    private String testMethodGet(String arg){
        System.out.println(this.name + "调用调用成功,传递的参数是"  + arg);
        return "调用成功";
    }
}

除了获取构造方法,我们还可以使用反射获取其成员变量,包括其记录值、修饰符、数据类型等。

复制代码
        //在刚刚我们使用反射创建了一个对象
        Student xiaoming = (Student) declaredConstructor.newInstance("xiaoming");
        System.out.println(xiaoming);

        //我们使用字节码对象调用其方法获得我们的成员变量name
        Field name = clazz.getDeclaredField("name");

        //由于其变量是private修饰,所以我们需要禁用其权限校验
        name.setAccessible(true);
        //通过get方法可以获取其记录值
        String nameByXiaoMing = (String) name.get(xiaoming);

        System.out.println(nameByXiaoMing);
        //使用set可以修改其记录值
        name.set(xiaoming,"xiaohong");

        System.out.println(name.get(xiaoming));

结果如下:

同样我们还可以获得其内部方法:

复制代码
        //获取方法
        Method testMethodGet = clazz.getDeclaredMethod("testMethodGet", String.class);
        //由于该方法时private
        testMethodGet.setAccessible(true);
        //需要传入调用的对象以及调用所需的参数,如果是空参可省略,有返回值则可以进行接收
        String result = (String) testMethodGet.invoke(xiaoming, "塔斯汀");

        System.out.println(result);

结果如下:

总结

相关推荐
源码云商2 小时前
基于Spring Boot + Vue的母婴商城系统( 前后端分离)
java·spring boot·后端
学习编程的gas5 小时前
C++面向对象编程入门:从类与对象说起(一)
开发语言·c++
冼紫菜5 小时前
【Spring Boot 多模块项目】@MapperScan失效、MapperScannerConfigurer 报错终极解决方案
java·开发语言·mybatis
还听珊瑚海吗5 小时前
基于SpringBoot的抽奖系统测试报告
java·spring boot·后端
Bear on Toilet5 小时前
Bug日记——实现“日期类”
开发语言·c++·bug
练习本5 小时前
Android系统架构模式分析
android·java·架构·系统架构
apcipot_rain5 小时前
《面向对象程序设计-C++》实验五 虚函数的使用及抽象类
开发语言·c++
明月看潮生8 小时前
青少年编程与数学 02-019 Rust 编程基础 05课题、复合数据类型
开发语言·青少年编程·rust·编程与数学
心灵宝贝8 小时前
IDEA 安装 SpotBugs 插件超简单教程
java·macos·intellij-idea