(JAVA)-反射

news2024/9/22 2:04:44

什么是反射?

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

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

关于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结合。

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

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

相关文章

打造炫酷粒子效果的前端利器tsParticles

前端潮流速递 &#xff1a;打造炫酷粒子效果的前端利器tsParticles 在现代前端开发中&#xff0c;动画和视觉效果是吸引用户的关键元素之一。而实现炫酷而引人入胜的粒子效果&#xff0c;常常需要耗费大量的时间和精力。然而&#xff0c;有了 tsParticles&#xff0c;这一切变…

GitHub上的15000个Go模块存储库易受劫持攻击

内容概要&#xff1a; 目前研究发现&#xff0c;GitHub上超过15000个Go模块存储库容易受到一种名为“重新劫持”的攻击。 由于GitHub用户名的更改会造成9000多个存储库容易被重新劫持&#xff0c;同时因为帐户删除&#xff0c;会对6000多个存储库造成重新劫持的危机。目前统计…

【MySQL·8.0·源码】MySQL 表的扫描方式

前言 在进一步介绍 MySQL 优化器时&#xff0c;先来了解一下 MySQL 单表都有哪些扫描方式。 单表扫描方法是基表的读取基础&#xff0c;也是完成表连接的基础&#xff0c;熟悉了基表的基本扫描方式&#xff0c; 即可以倒推理解 MySQL 优化器层的诸多考量。 基表&#xff0c;即…

半导体行业-SECS/GEM协议 JAVA与SECS/GEM通信 什么是配方?springboot集成SECS通信协议 配方管理S7FX

Java与SECS基础通信 Java实现SECS指令S2F17获取时间 Java实现SECS指令 S10F3 终端单个显示例子 Java实现SECS指令 S7FX配方管理 Java实现SECS指令 S5F1报警/取消报警上传 实例源码及DEMO请查阅 JAVA开发SECS快速入门资料&#xff0c;SECS S7F19 什么是半导体配方&…

Unity3D UGUI图集打包与动态使用(TexturePacker)

制作图集的好处&#xff1a; 众所周知CPU是用来处理游戏的逻辑运算的&#xff0c;而GPU是用来处理游戏中图像的。在GPU中&#xff0c;我们要绘制一个图像需要提交图片&#xff08;纹理&#xff09;到显存&#xff0c;然后再进行绘制&#xff08;在这个过程中会产生一次DrawCall…

书生-浦路大模型全链路开源体系

2023年&#xff0c;大模型成为热门关键词 论文链接 大模型已经成为发展通用人工智能的重要途经 模型评测过程&#xff1a;从模型到应用 全链条开源开发体系 | 数据&#xff1a; 多模态融合 万卷包含文本、图像和视频等多模态数据&#xff0c;涵盖科技、文学、媒体、教育和法…

力扣hot100 二叉树的层序遍历 BFS 队列

&#x1f468;‍&#x1f3eb; 题目地址 时间复杂度&#xff1a; O ( n ) O(n) O(n)空间复杂度&#xff1a; O ( n ) O(n) O(n) &#x1f60b; 队列写法 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode…

Pycharm恢复默认设置

window 系统 找到下方目录-->删除. 再重新打开Pycharm C:\Users\Administrator\.PyCharm2023.3 你的不一定和我名称一样 只要是.PyCharm*因为版本不同后缀可能不一样 mac 系统 请根据需要删除下方目录 # Configuration rm -rf ~/Library/Preferences/PyCharm* # Caches …

vue的小入门

vue的快速上手 Vue概念 是一个用于构建用户界面的渐进式框架优点&#xff1a;大大提高开发效率缺点&#xff1a;需要理解记忆规则 创建Vue实例 步骤&#xff1a; 准备容器引包创建Vue实例new Vue()指定配置项el data>渲染数据 el指定挂载点&#xff0c;选择器指定控制…

OpenCV-14图片的四则运算和图片的融合

一、图片的四则运算 1. 加法运算 通过使用API add来执行图像的加法运算 cv2.add&#xff08;src1&#xff0c; src2&#xff09;需要再其中传入两张图片。 图片就是矩阵&#xff0c;图片的加法运算就是矩阵的加法运算。 因此加法运算中要求两张图的shape必须是相同的。 首…

【vue/uniapp】使用 uni.chooseImage 和 uni.uploadFile 实现图片上传(包含样式,可以解决手机上无法上传的问题)

引入&#xff1a; 之前写过一篇关于 uview 1.x 版本上传照片 的文章&#xff0c;但是发现如果是在微信小程序的项目中嵌入 h5 的模块&#xff0c;这个 h5 的项目使用 u-upload 的话&#xff0c;图片上传功能在电脑上正常&#xff0c;但是在手机的小程序上测试就不会生效&#x…

C# windows服务程序开机自启动exe程序

我们使用传统的Process.Start(".exe")启动进程会遇到无法打开UI界面的问题&#xff0c;尤其是我们需要进行开启自启动程序设置时出现诸多问题&#xff0c;于是我们就想到采用windows服务开机自启动来创建启动一个新的exe程序&#xff0c;并且是显式运行。 首先是打开…

19、BLIP-2

简介 github 通过利用预训练的视觉模型和语言模型来提升多模态效果和降低训练成本&#xff0c;预训练的视觉模型能够提供高质量的视觉表征&#xff0c;预训练的语言模型则提供了强大的语言生成能力。 实现过程 为了弥合模态差距&#xff0c;提出了一个分两个阶段预训练的 Qu…

华为端口隔离高级用法经典案例

最终效果&#xff1a; pc4不能ping通pc5&#xff0c;pc5能ping通pc4 pc1不能和pc2、pc3通&#xff0c;但pc2和pc3能互通 vlan batch 2 interface Vlanif1 ip address 10.0.0.254 255.255.255.0 interface Vlanif2 ip address 192.168.2.1 255.255.255.0 interface MEth0/0/1 i…

神经网络:经典模型热门模型

在这里插入代码片【一】目标检测中IOU的相关概念与计算 IoU&#xff08;Intersection over Union&#xff09;即交并比&#xff0c;是目标检测任务中一个重要的模块&#xff0c;其是GT bbox与pred bbox交集的面积 / 二者并集的面积。 下面我们用坐标&#xff08;top&#xff0…

Windows定时重启Tomcat

项目场景&#xff1a; 系统&#xff1a;Windows 7 Tomcat&#xff1a;apache-tomcat-8.0.5 JDK&#xff1a;1.8 问题描述 最近项目的Tomcat隔一段时间就假死&#xff0c;最后想到的解决方式就是&#xff1a;每天凌晨1点重启tomact。 解决方案&#xff1a; 使用Windows系统…

基于SpringBoot的旅游网站

目录 前言 开发环境以及工具 项目功能介绍 用户端&#xff1a; 管理端&#xff1a; 详细设计 用户端首页 登录页面 管理端页面 源码获取 前言 本项目是一个基于IDEA和Java语言开发基于SpringBoot的旅游网站。应用包含管理端和用户端等多个功能模块。 改革开放以来&am…

MatrixOne 1.1.0 Release

我们非常高兴地宣布&#xff1a; MatrixOne内核1.1.0版本 正式发布啦&#xff01; 项目文档网站 https://docs.matrixorigin.cn MatrixOne是一款分布式超融合异构数据库&#xff0c;MatrixOne旨在提供一个云原生、高性能、高弹性、高度兼容MySQL的HSTAP数据库&#xff0c;让…

【数据挖掘】基于 LightGBM 的系统访问风险识别(附源码)

基于 LightGBM 的系统访问风险识别 文章目录 基于 LightGBM 的系统访问风险识别一、课题来源二、任务描述三、课题背景四、数据获取分析及说明&#xff08;1&#xff09;登录https://www.datafountain.cn并获取相关数据&#xff08;2&#xff09;数据集文件说明&#xff08;3&a…

Cytoscape 3.10安装包下载及安装教程

Cytoscape3.10下载链接&#xff1a;https://docs.qq.com/doc/DUkpuR0RVU0JVWkFP 1、选中下载好的安装包&#xff0c;右键选择解压到“Cytoscape 3.10”文件夹 2、双击打开“Cytoscape_3_10_0_windows_64bit.exe” 3.点击“Download”&#xff0c;请耐心等待“Java”完成 4、点击…