(JAVA)-反射

什么是反射?

反射允许对成员变量,成员方法和构造方法的信息进行编程访问。

说简单点就是反射能将类里面的构造方法,成员变量,修饰符,返回值,注解,类型,甚至异常等类里面的所有东西都能够获取出来。

关于Class的介绍:Class类是用来描述类的类,它是一个十分特殊的类,没有构造方法。Class对象的加载过程如下:当程序运行时,我们编写的每一个类都会被编译生成 类名.class 文件,当我们我们new对象或者类加载器加载的时候,JVM就会加载我们的 类名.class 文件并且加载到内存中,即当一个类加载完成之后,在堆内存的方法区中就生成了一个该类唯一的Class对象(一个类只会对应一个Class对象,绝对不会产生第二个),这个Class对象就包含了完整的类的结构信息,用于表示该类的所有信息。

但是我们获取不是从java文件中获取的,而是从class字节码文件中获取的,所以我们先来讲一讲如何获取字节码文件对象。

一:反射获取类对象

java代码运行可以分为以下几个阶段:

1.源代码阶段:编写java文件,然后把他编译成字节码文件。没有把代码加载到内存当中,只是在硬盘进行操作。

2.加载阶段:把字节码文件加载到内存当中

3.运行阶段:在内存当中获取对象

以下三种获取对象的方式分别对应着上面三个阶段获取:

1.Class.forNmae("全类名");      2.类名.class;      3.对象.getClass;

这里所有举例都用student类来作为演示,所以先创建一个student类,后面会一直用这个。

package H;
//创建学生类
public class student {
    private String name;
    private int age;

    public student() {
    }

    public student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    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;
    }

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

   

 获取类对象的三种方法

 public static void main(String[] args) throws ClassNotFoundException {
        Class aClass = Class.forName("H.student");
        Class bClass =student.class;//最为常用
        student s=new student();//当作参数进行传递
        Class cclass=s.getClass();//已经有了这个类的对象才可以使用
    }
}

二:反射获取构造方法

Constructor就是java中构造方法的类

 演示以下:

public class test {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
        Class aClass = Class.forName("H.student");//最为常用
        Class bClass =student.class;//当作参数进行传递
        student s=new student();
        Class cclass=s.getClass();//已经有了这个类的对象才可以使用
        Constructor[] constructors1 = aClass.getConstructors();//获取全部公共构造方法
        Constructor[] constructors2 = aClass.getDeclaredConstructors();//获取全部构造方法
        Constructor constructor1 = aClass.getConstructor(String.class,int.class);//获取参数传递的类型的构造方法
        Constructor constructor2 = aClass.getDeclaredConstructor();//
    }
}

获取到Constructor对象可以调用Constructor类中的getModifiers方法获取他的权限修饰符。

打印出来的结果是整形形式,代表不同的权限修饰符。

int modifiers=constructor1.getModifiers();

用获取到的构造方法创建对象:

1.形参需要跟构造对象一致。

2.当构造是私有方法时,不能直接创建对象,需要使用setAccssible方法临时取消权限校验(暴力反射)。

sonstructor1.setAccessible(ture);
student stu=(student) constructor1.newInstance("张三",23);

三:反射获取成员变量

field就是java中成员变量的类

  Field field = aClass.getField("name");

获取成员变量的权限修饰符:打印出来的结果是整形形式,代表不同的权限修饰符。

int modifiers=field.getModifiers();

获取成员的成员变量名:

String n=field.getType();

 获取成员的数据类型:

Class<?> type=name.getTypt();

获取成员变量记录的值:

当成员是私有时,需要使用setAccssible方法临时取消权限校验(暴力反射),来查看对象的值

student s=new student("张三","23");
name.setAccessible(true);
Object values=name.get(s);

修改对象里记录的成员变量的值:

当成员是私有时,需要使用setAccssible方法临时取消权限校验(暴力反射),来修改对象的值

name.set(a,"诩子");

四:反射获取成员方法:

Method类就是java类中的成员方法的类

1.获取成员方法

 Method[] methods = aClass.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }

method m=class.getMethod("eat",String.class);

注意:getMethod方法包括从父类继承的方法。

获取方法的名字:

String name=m.getName();

获取方法的形参:

int num =m.getParameterCount();//获取形参个数
Class<>[] p=m.getParameterTypes();//获取形参类型
Paramemter[] parameters=m.getParameters();//获取方法的形参

获取方法抛出的异常:

Class<?>[] exceptionTypes=m.getExceptionTypes();

运行方法:当成员是私有时,需要使用setAccssible方法临时取消权限校验(暴力反射),来修改对象的值

object invoke(Object obj,object... args)
//参数一:方法调用者,用obj对象调用该方法
//参数二:方法的形参
//参数三:方法的返回值,当没有返回值就不写
students s=new students();
m.invoke(s,"汉堡包");

 细节:我们发现当操作到私有化的参数且是跟实际对象有关的操作(查看对象数值,修改对象数值),需要使用暴力反射。

反射的作用:

1.获取一个类里面的所有的信息,获取到了之后,再执行其他的业务逻辑

2.结合配置文件,动态的创建对象并调用方法。

我们通过两个小练习来体现:

test1:保存对象所有的字段名和值到文件中

public class test {
    public static void main(String[] args) throws IllegalAccessException, IOException {
        student s=new student("诩",18,'女',168,"熬夜");
        teacher t=new teacher("俊",10000);
        saveObject(s);
    }
    public static void saveObject(Object obj) throws IllegalAccessException, IOException {
        BufferedWriter bw=new BufferedWriter(new FileWriter("D:\\code\\javaee\\myFrect\\src\\test"));
        Class aClass = obj.getClass();
        Field[] fidles = aClass.getDeclaredFields();
        for (Field fidle : fidles) {
            fidle.setAccessible(true);
            String name=fidle.getName();
            Object value = fidle.get(obj);
      bw.write(name+"="+value);
      bw.newLine();
        }
        bw.close();
    }
}

test2:通过配置文件动态创建对象

  public static void main(String[] args) throws IOException {
        Properties prop =new Properties();
        prop.put("className","D:\\code\\javaee\\myFrect\\src\\H2\\student.java");
        prop.put("methodName","study");
        FileOutputStream fos = new FileOutputStream("D:\\code\\javaee\\myFrect\\src\\prop.properties");
        prop.store(fos,"无");
        fos.close();
        Properties prop1 =new Properties();
        FileInputStream fis=new FileInputStream("D:\\code\\javaee\\myFrect\\src\\prop.properties");
        prop1.load(fis);
        String className=(String)prop1.get("className");
        String methodName=(String)prop1.get("methodName");
        System.out.println(className);
        System.out.println(methodName);
        fis.close();
    }

注意:配置文件是一个特殊的双列集合,里面有方法能跟IO结合。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Canvas保姆级教程----深入解析HTML5 Canvas工作原理和常用方法

&#x1f4e2; 鸿蒙专栏&#xff1a;想学鸿蒙的&#xff0c;冲 &#x1f4e2; C语言专栏&#xff1a;想学C语言的&#xff0c;冲 &#x1f4e2; VUE专栏&#xff1a;想学VUE的&#xff0c;冲这里 &#x1f4e2; CSS专栏&#xff1a;想学CSS的&#xff0c;冲这里 &#x1f4…

8086CPU的寻址方式(7种)

基本概念 立即操作数&#xff1a;操作数包含在指令中寄存器操作数&#xff1a;操作数包含在CPU的某个内部寄存器中存储器操作数&#xff1a;约定操作数事先存放在存储器中存放数据的某个单元基本格式 MOV xx,yy xx&#xff1a;目的操作数字段 yy&#xff1a;源操作数字段 EA&a…

英飞凌AURIX 2G TC3xx新一代芯片架构系列介绍-概论

英飞凌AURIX 2G TC3xx新一代芯片架构系列介绍-概论

普中STM32-PZ6806L开发板(HAL库函数实现-温度传感器DS18B20)

简介 主芯片STM32F103ZET6, 通过引脚PG11 连接DS18B20, 读取DS18B20采集的温度数据;电路原理图 DS18B20电路图 DS18B20 与 主芯片连接引脚 其他知识 DS18B20资料 DS18B20数据手册 DS18B20 简介 单线通讯的温度传感器, 测量温度在-55℃ 到 125℃&#xff0c; 在-10C 到…

python 知识点

ping ping 不能带协议&#xff0c;如&#xff1a;ping baidu.com 引入包顺序 分三级&#xff0c;第一级是 Python 的内置库&#xff0c;第二级是第三方库&#xff0c;第三级是自己的代码。每一级用一个空行间隔 运算符 keyError&#xff1a;key不存在 列表推导式 创建字典 字…

华芯微特|MCU之TIMER输入捕获

引言 华芯微特公司SWM系列单片机提供的TIMER个数和功能有些微差别&#xff0c;为了让您更加简单的使用这一功能&#xff0c;下面小编将以SWM190为例&#xff0c;我们今天详细讲解一下TIMER的输入捕获功能。 TIMER输入捕获 一、TIMER定时器之输入捕获功能 我们今天详细讲解一下…

网络安全—SSL安全访问应用

文章目录 网络拓扑部署CA服务器颁发证书开启Web服务安装IIS服务修改Web默认网页 申请Web证书前提准备申请文件生成申请web证书开始安装web证书 客户机访问web默认网站使用HTTP使用HTTPS 为客户机安装浏览器证书 环境&#xff1a;Windows Server 2003 网络拓扑 这里使用NAT还是…

输入输出流

1.输入输出流 输入/输出流类&#xff1a;iostream---------i input&#xff08;输入&#xff09; o output&#xff08;输出&#xff09; stream&#xff1a;流 iostream&#xff1a; istream类&#xff1a;输入流类-------------cin&#xff1a;输入流类的对象 ostream类…

潮玩宇宙大逃杀游戏搭建

潮玩宇宙是当下较火的社交互动平台&#xff0c;它不仅涵盖了各种潮玩商品&#xff0c;还拥有各种游戏玩法&#xff0c;尤其是大逃杀游戏非常火爆&#xff01;本文将介绍大逃杀游戏的开发和发展前景。 大逃杀游戏 大逃杀游戏是当下的一种新型游戏模式&#xff0c;旨在为玩家提供…

python django 生鲜商城管理系统

python django 生鲜商城管理系统,包含用户端和管理端 功能&#xff1a; 用户端&#xff1a;商城主页展示&#xff0c;登录&#xff0c;注册&#xff0c;用户中心&#xff0c;购物车&#xff0c;我的订单&#xff0c;购物车结算 管理端&#xff1a;登录&#xff0c;商品&…

[C#]使用纯opencvsharp部署yolov8-onnx图像分类模型

【官方框架地址】 https://github.com/ultralytics/ultralytics.git 【算法介绍】 YOLOv8 是一个 SOTA 模型&#xff0c;它建立在以前 YOLO 版本的成功基础上&#xff0c;并引入了新的功能和改进&#xff0c;以进一步提升性能和灵活性。具体创新包括一个新的骨干网络、一个新…

【设计模式】二十一.行为型模式之状态模式

状态模式 一. 说明 状态模式通常描述一个类不同行为的多个状态变更&#xff0c;对象的行为依赖它的状态&#xff0c;它是一种行为型模式。 状态模式可以用来消除代码中大量的if-else结构&#xff0c;它明确对象是有状态的、对象的不同状态对应的行为不一样、行为之间是可以切…

Winform中使用Fleck实现Websocket服务端并读取SQLite数据库中数据定时循环群发消息

场景 Winform中使用Websocket4Net实现Websocket客户端并定时存储接收数据到SQLite中&#xff1a; Winform中使用Websocket4Net实现Websocket客户端并定时存储接收数据到SQLite中-CSDN博客 Winform中操作Sqlite数据增删改查、程序启动时执行创建表初始化操作&#xff1a; Wi…

计算机基础面试题 |08.精选计算机基础面试题

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

前端框架中的状态管理(State Management)

聚沙成塔每天进步一点点 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 欢迎来到前端入门之旅&#xff01;感兴趣的可以订阅本专栏哦&#xff01;这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发…

【算法每日一练]-dfs bfs(保姆级教程 篇8 )#01迷宫 #血色先锋队 #求先序排列 #取数游戏 #数的划分

目录 今日知识点&#xff1a; 使用并查集映射点&#xff0c;构造迷宫的连通块 vis计时数组要同步当回合的处理 递归求先序排列 基于不相邻的取数问题&#xff1a;dfs回溯 n个相同球放入k个相同盒子&#xff1a;dfs的优化分支暴力 01迷宫 血色先锋队 求先序排列 取数游…

【ikbp】数据可视化DataV

天天查询一些数据&#xff0c;希望来一个托拉拽的展示&#xff0c;部署体验一下可视化大屏 快速搭建快速查询实时更新简单易用 启动服务 数据可视化 静态查询 配置数据 过滤数据 分享

计算机网络—网络搭建NAT内外网映射

使用Windows Server 2003 网络拓扑 Router 外网&#xff1a;NAT IP 网段 192.168.17.0/24内网&#xff1a;仅主机模式 IP 172.16.29.4 Client1&#xff1a;仅主机模式 IP 172.16.29.2 网关 172.16.29.1 Client2&#xff1a;仅主机模式 IP 172.16.29.3 网关 172.16.29.1…

数字信号处理期末复习——计算小题(二)

个人名片&#xff1a; &#x1f981;作者简介&#xff1a;一名喜欢分享和记录学习的在校大学生 &#x1f42f;个人主页&#xff1a;妄北y &#x1f427;个人QQ&#xff1a;2061314755 &#x1f43b;个人邮箱&#xff1a;2061314755qq.com &#x1f989;个人WeChat&#xff1a;V…

uni-app中实现元素拖动

uni-app中实现元素拖动 1、代码示例 <template><movable-area class"music-layout"><movable-view class"img-layout" :x"x" :y"y" direction"all"><img :src"musicDetail.bgUrl" :class&…