【JavaSE】反射

news2024/11/19 23:35:29

一、概念

反射是在运行期间,动态获取对象的属性和方法

二、相关的类

在Java的反射里主要有以下几个类:Class类,这是反射的起源,反射必须要先获取Class对象,其次是Field类,当我们需要通过反射获取私有字段时就需要用到这个类,Method类,同理我们获取私有方法时就需要用到这个类

三、获取Class对象

要进行反射就必须先获取目标类对应的Class对象,主要有以下三种方法:

我们先定义一个学生类:主要字段有姓名、班级、年龄都是私有,其中一个公开的无参构造方法,一个私有含参构造方法,还有一个私有的eat方法

class Student{
    private String name;
    private String classes;
    private int age;

    public Student() {
    }

    private Student(String name,String classes,int age){
        this.name = name;
        this.classes = classes;
        this.age = age;
    }

    private void eat(String s){
        System.out.println(this.classes + "的" + this.name +"上课偷吃"+s);
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", classes='" + classes + '\'' +
                ", age=" + age +
                '}';
    }
}

然后我们通过以下三种方法获取Class对象

    • 目标类.class

public class GetConstruct {
    public static void main(String[] args) {
        //1.获取Class对象
        Class<?> c1 = Student.class;
        Class<?> c2 = new Student().getClass();
        Class<?> c3 = Class.forName("Student");
    }
}
    • 目标类实例.getClass()

    • Class.forName(目标类名)

三、反射创建实例

获取到Class实例后就可以通过Class实例的方法来构造目标类的对象

    • Class类的newInstance方法

public class GetConstruct {
    public static void main(String[] args) throws InstantiationException, IllegalAccessException {
        //1.获取Class对象
        Class<?> c1 = Student.class;
        Class<?> c2 = new Student().getClass();
        //Class<?> c3 = Class.forName("反射.Student");
        
        //2.创建实例
        Student student1 = (Student) c1.newInstance();
    }
}
    • 通过获取目标类的私有构造方法

先获取Class对象,然后利用他的getDeclaredConstructor方法获取私有构造方法

public class GetConstruct {
    public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        //1.获取Class对象
        Class<?> c1 = Student.class;
        Class<?> c2 = new Student().getClass();
        //Class<?> c3 = Class.forName("反射.Student");

        //2.创建实例
        Constructor<?> constructor = c1.getDeclaredConstructor(String.class,String.class,int.class);
        constructor.setAccessible(true);  //确认获取
        Student student = (Student) constructor.newInstance("张三","21级3班",21);//传入参数

        //3.验证
        System.out.println(student);
    }
}

四、反射获取私有字段

依旧先是获取Class对象然后利用反射创建目标类的实例 ,最后使用Field类获取修改字段

public class GetField {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {
        //1.获取Class对象
        Class<?> c1 = Student.class;
        //Class<?> c2 = new Student().getClass();
        //Class<?> c3 = Class.forName("反射.Student");

        //2.创建目标类实例
        Constructor<?> constructor = c1.getDeclaredConstructor(String.class,String.class,int.class);
        constructor.setAccessible(true);
        Student student = (Student) constructor.newInstance("张三","21级4班",21);

        //3.利用Field类的方法修改字段
        Field field = c1.getDeclaredField("name");   //参数传入要获取的字段名
        field.setAccessible(true);                         //确认获取
        field.set(student,"李四");                          //参数:要修改的目标实例,新字段的值

        //4.验证
        System.out.println(student);
    }
}

五、反射获取私有方法

先获取Class实例,然后创建目标类对象,再通过Method类进行获取,调用 方法获取目类i私有方法

public class GetMethod {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
        //1.获取Class对象
        Class<?> c1 = Student.class;
        //Class<?> c2 = new Student().getClass();
        //Class<?> c3 = Class.forName("反射.Student")/;

        //2.创建目标类实例
        Constructor<?> constructor = c1.getDeclaredConstructor(String.class,String.class,int.class);
        constructor.setAccessible(true);
        Student student = (Student) constructor.newInstance("张三","21级4班",21);

        //3.通过Method方法获取
        Method method = c1.getDeclaredMethod("eat",String.class);  //参数传入要获取的方法名
        method.setAccessible(true);                         //确认获取
        method.invoke(student,"零食");                             //传入目标类的实例与函数参数
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/163179.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

老杨说运维 | 2023,浅谈智能运维趋势(一)

&#xff08;文末附视频回顾&#xff0c;一键直达精彩内容&#xff09; 前言&#xff1a; 2022年&#xff0c;是经济被影响的一年&#xff0c;这一年无论是企业还是个人经济形势都呈下滑趋势&#xff0c;消费降级状态或许不会因为2022的结束而改观。 全球经济紧缩的状态下&am…

不仅会编程还要会英语(博主英语小笔记)1.1名词

目录 1-1名词的概念和分类 1、名词的概念 2&#xff0e;名词根据其意义可以分为专有名词和普通名词 &#xff08;1&#xff09;专有名词&#xff1a; &#xff08;2&#xff09;普通名词&#xff1a; 1-1名词的概念和分类 1、名词的概念 名词是表示人、动物、地点、物品以…

字符串常用函数介绍及模拟实现

&#x1f40e;作者的话 本文介绍字符串常用的函数如何使用及其模拟实现~ 跳跃式目录strlen介绍strcpy介绍strcat介绍strcmp介绍strncpy介绍strncat介绍strncmp介绍strstr介绍strchr介绍strrchr介绍memcpy介绍memmove介绍memcmp介绍memset介绍strtok介绍strlen介绍 函数原型&…

GO语言配置和基础语法应用(二)

Go 语言结构 在我们开始学习 Go 编程语言的基础构建模块前&#xff0c;让我们先来了解 Go 语言最简单程序的结构。 Go Hello World 实例 Go 语言的基础组成有以下几个部分&#xff1a; 包声明引入包函数变量语句 & 表达式注释 接下来让我们来看下简单的代码 package ma…

Allegro如何导出placement操作指导

Allegro如何导出placement操作指导 在做PCB布局的时候,有时需要导出和导入Placement,placement文件是板上所有器件的坐标以及所在层面的文件 具体操作如下 导出placement文件,选择File

实现用户进程

文章目录前言前置知识实验操作实验一实验二前言 博客记录《操作系统真象还原》第十一章实验的操作~ 实验环境&#xff1a;ubuntu18.04VMware &#xff0c; Bochs下载安装 实验内容&#xff1a; 定义并初始化 TSS。实现用户进程。 前置知识 TSS 简介 TSS&#xff0c;即 Tas…

time和datetime之类的东西

这篇文章是学习数据可视化的记录&#xff0c;原视频链接 B站视频连接 time 先来看一张图 struct_time(时间元组)是作为时间戳和格式化后的字符串的桥梁的 mktime(t)是将指定时间元组转换为时间戳的 localtime()是将指定时间戳转换为时间元组的&#xff0c;可以不写时间戳&…

【一文教你学会动态内存管理】

1.为什么会存在动态内存分配&#xff1f; 2. 动态内存函数的介绍 2.1 malloc函数和free函数 2.2 calloc函数 2.3 realloc 3. 常见的动态内存错误 3.1 对NULL指针的解引用操作 3.2 对动态开辟空间的越界访问 3.3 对非动态开辟内存使用free释放 3.4 使用free释放一块动态开…

Uniswap v3 详解(一):设计原理

刚看完 Uniswap v2 的代码&#xff0c;本来打算写一个 Uniswap v2 设计与实现&#xff0c;结果 Uniswap v3 就发布了。趁着这个机会就先写一个 Uniswap v3 设计与实现吧。 因为 v3 版本的实现复杂度和 v2 已经不在一个量级了&#xff0c;难免会有理解上的偏差&#xff0c;本文…

ESP8266-01s+STM32+MQTT+ONNET+EMQX实现定时发送心跳包并配置MQTT断开连接后进行重连

目录:1.情况介绍2.发送心跳包和MQTT重连实现步骤3.运行效果1.情况介绍 硬件通过ESP8266-01s连接自己的MQTT服务器EMQX的时候&#xff0c;发现连上后没过多久就自动断开了&#xff0c;由于硬件代码使用的是ONNET的案例代码改的&#xff0c;所以发现该案例代码并没有发送心跳包和…

测试篇(一):需求、BUG、测试用例、开发模型和测试模型、配置管理和软件测试

目录一、什么是需求1.1 需求的概念1.2 用户需求1.3 软件需求二、什么是测试用例2.1 测试用例的概念三、什么是BUG3.1 BUG(软件错误)的概念四、开发模型4.1 软件生命周期4.2 瀑布模型4.3 螺旋模型4.4 增量、迭代模型4.5 敏捷模型五、测试模型5.1 软件测试V模型5.2 软件测试W模型…

(详细简单成功版本)Mysql主从复制

博主不易&#xff0c;如果有帮助点个赞加个关注再走啊家人们 目录 介绍 配置-前置条件 大坑&#xff1a;如果两份mysql文件都是复制的一份&#xff0c;那么就修改其中一份的uuid&#xff0c;要不后续配置不成功 配置-主库Master 1.修改Mysql数据库的配置文件my.ini 2.重启…

mysql快速生成100W条测试数据(6)地区天气情况并存入mysql数据库

这是之前的文章里面包含一些以前的一些操作流程可以进行参考学习 更加详细操作步骤在第一篇文章里面 mysql快速生成100W条测试数据&#xff08;1&#xff09;&#xff1a;游戏人物数据 mysql快速生成100W条测试数据&#xff08;2&#xff09;公司员工信息 mysql快速生成100W条测…

202:vue+openlayers: easing的API及在view.animation中使用示例

第202个 点击查看专栏目录 本示例的目的是介绍如何在vue+openlayers项目中使用easing。 easing在openlayers共用五种表现形式,easeIn,easeOut,inAndOut,linear,upAndDown。 easing主要在view.animation中使用。 名称说明easeIn开始慢,然后加速easeOut开始快,然后加速inA…

PyTorch实例3——迁移学习

传送门&#xff1a;蓝桥云课实验 目录1. 实验环境2. 实验目的3. 相关原理4. 实验步骤4.1 数据收集4.1.1加载数据4.1.2 GPU运算4.2 数据预处理4.3 创建模型4.3.1 构建迁移模型4.3.2 训练模型测试绘制图表4.3.2.1 预训练模式4.3.2.2 固定值模式4.4 结论1. 实验环境 Jupyter Note…

【JavaGuide】数据库基础知识总结

数据库基础知识总结1.什么是元组, 码, 候选码, 主码, 外码, 主属性, 非主属性&#xff1f;2.主键和外键有什么区别?3.什么是 ER 图&#xff1f;4.数据库的三范式5.drop、delete 与 truncate 区别&#xff1f;1.什么是元组, 码, 候选码, 主码, 外码, 主属性, 非主属性&#xff…

el-switch 开关文字显示在开关里面

提示&#xff1a; active-color"#305BE7" active-text"开" 打开时的背景颜色和内容 inactive-color"#7D8294" inactive-text"关" 关闭时的背景颜色和内容 内容&#xff1a; <el-switch v-model"value2" class&qu…

Java 基础之文件处理

1. Stream 流 2. File 和 IO Java.io 包几乎包含了所有操作输入、输出需要的类。所有这些流类代表了输入源和输出目标&#xff1a; 2.1 控制台输入 Java 的控制台输入由 System.in 完成&#xff0c; 将 System.in 包装在一个 BufferedReader 对象中来创建一个字符流&#x…

大数据必学Java基础(一百二十二):POM模式-Maven工程关系

文章目录 POM模式-Maven工程关系 一、依赖 1、特性:依赖的传递性 2、原则:两个原则

[Linux]冯诺依曼体系结构

&#x1f941;作者&#xff1a; 华丞臧. &#x1f4d5;​​​​专栏&#xff1a;【LINUX】 各位读者老爷如果觉得博主写的不错&#xff0c;请诸位多多支持(点赞收藏关注)。如果有错误的地方&#xff0c;欢迎在评论区指出。 推荐一款刷题网站 &#x1f449; LeetCode刷题网站 文…