Java反射之获取构造方法,成员变量,成员方法以及反射的作用

news2024/9/25 7:19:28

目录

  • 1.什么是反射
  • 2.获取Class对象的三种方式
  • 3.反射获取构造方法
  • 4.反射获取成员变量
  • 5.反射获取成员方法
  • 6.反射的作用

1.什么是反射

在Java中,反射是指程序在运行时动态地获取类的信息、调用方法和访问属性的能力。
通过反射,可以在运行时获取类的构造函数、方法和字段等信息,并且可以在运行时动态地创建对象、调用方法和访问属性,而不需要在编译时知道类的具体信息。
反射提供了一种机制,使得编写通用的、灵活的代码成为可能,但同时也会增加代码的复杂性和性能开销。

反射允许对封装类的字段(成员变量),方法(成员方法)和构造函数(构造方法)的信息进行编程访问。

在这里插入图片描述

2.获取Class对象的三种方式

Class.forName("全类名");

		//全类名:包名+类名
        Class clazz1 = Class.forName("case11.Student");//最常用

类名.class

		 //一般当作参数进行传递
        Class clazz2 = Student.class;

对象.getClass();

		Student s = new Student();
        Class clazz3 = s.getClass();

3.反射获取构造方法

创建一个Student类:定义多种构造方法

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

    public Student() {
    }

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

    protected Student(int age) {
        this.age = age;
    }

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

主函数:演示反射获取构造方法的各种函数

public class Main{
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        //获取class字节码文件对象
        Class clazz = Class.forName("case11.Student");
        //获取public构造方法
        Constructor[] cons = clazz.getConstructors();
        for (Constructor con : cons) {
            System.out.println(con);
        }

        System.out.println("-------------------------");
        //获取所有构造方法
        Constructor[] con1 = clazz.getDeclaredConstructors();
        for (Constructor constructor : con1) {
            System.out.println(constructor);
        }

        System.out.println("-------------------------");
        //获取空参构造方法
        Constructor con2 = clazz.getDeclaredConstructor();
        System.out.println(con2);

        System.out.println("-------------------------");
        //获取带参数的构造方法
        System.out.println(clazz.getDeclaredConstructor(String.class));
        System.out.println(clazz.getDeclaredConstructor(int.class));
        Constructor con3 = clazz.getDeclaredConstructor(String.class, int.class);
        System.out.println(con3);

        System.out.println("------------------------");

        //获取构造方法的权限修饰符
        int modifiers = con3.getModifiers();
        System.out.println(modifiers);
        //获取构造方法的参数
        Parameter[] parameters = con3.getParameters();
        for (Parameter parameter : parameters) {
            System.out.println(parameter);
        }
        //暴力反射:临时取消权限的校验
        con3.setAccessible(true);
        //创建对象
        Student student = (Student) con3.newInstance("张三", 123);
        System.out.println(student);
    }
}

4.反射获取成员变量

①Class类中用于获取成员变量的方法:
Field[] getFields():返回所有公共成员变量对象的数组
Field[] getDeclaredFields(): 返回所有成员变量对象的数组
Field getField(String name): 返回单个公共成员变量对象
Field getDeclaredField(String name): 返回单个成员变量对象

②Field类中用于创建对象的方法:
void set(Object obj,Object value): 赋值
Object get(Object obj) 获取值。

创建一个Student类:

public class Student {
    private String name;
    private int age;
    public String gender;

    public Student() {
    }

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

主函数:利用反射修改成员变量

public class Main{
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
        //获取class字节码文件的对象
        Class<?> clazz = Class.forName("case12.Student");
        //获取公共的成员变量
        Field[] fields = clazz.getFields();
        for (Field field : fields) {
            System.out.println(field);//public java.lang.String case12.Student.gender
        }
        //获取所有的成员变量
        Field[] fields1 = clazz.getDeclaredFields();
        //获取单个的成员变量
        Field gender = clazz.getField("gender");
        //获取私有的成员变量
        Field name = clazz.getDeclaredField("name");
        //获取权限修饰符
        int modifiers = name.getModifiers();
        //获取成员变量名name的值
        String n = name.getName();
        //获取成员变量数据类型
        Class<?> type = name.getType();
        System.out.println(type);//class java.lang.String
        //获取成员变量记录的值
        Student s = new Student("zhangsan", 23, "男");
        //临时取消访问权限
        name.setAccessible(true);
        Object value = name.get(s);
        System.out.println(value);//zhangsan
        //修改对象里面记录的值
        name.set(s, "lisi");
        System.out.println(s);//Student{name = lisi, age = 23, gender = 男}
    }
}

5.反射获取成员方法

①class类中用于获取成员方法的方法:
Method[] getMethods(): 返回所有公共成员方法对象的数组,包括继承的
Method[] getDeclaredMethods(): 返回所有成员方法对象的数组,不包括继承的
Method getMethod(String name, Class<?>... parameterTypes): 返回单个公共成员方法对象 Method getDeclaredMethod(String name, Class<?>… parameterTypes): 返回单个成员方法对象

②Method类中用于创建对象的方法:
Object invoke(Object obj, Object… args): 运行方法
参数一:用obj对象调用该方法
参数二:调用方法的传递的参数(如果没有就不写
返回值:方法的返回值(如果没有就不写)

定义一个Student类:

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

    public Student() {
    }

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

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

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

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

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

    public void sleep() {
        System.out.println("睡觉");
    }

    private void eat(String something) throws IOException, NullPointerException, ClassCastException {
        System.out.println("在吃" + something);
    }

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

主函数:演示反射获取成员方法

public class Main{
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        //获取class字节码文件对象
        Class<?> clazz = Class.forName("case13.Student");
        //获取公共的所有的方法对象
        Method[] methods = clazz.getMethods();
        for (Method method : methods) {
            System.out.println(method);//包含了父类中的所有的公共方法
        }
        //获取所有的方法但不能获取父类的方法,但可以获取本类中私有方法
        Method[] methods1 = clazz.getDeclaredMethods();
        //获取私有的单个方法
        Method m = clazz.getDeclaredMethod("eat", String.class);
        //获取方法的修饰符
        int modifiers = m.getModifiers();
        //获取方法的名字
        String name = m.getName();
        //获取方法的形参
        Parameter[] parameters = m.getParameters();
        for (Parameter parameter : parameters) {
            System.out.println(parameter);//java.lang.String arg0
        }
        //获取方法抛出的异常
        Class[] exceptionTypes = m.getExceptionTypes();
        for (Class exceptionType : exceptionTypes) {
            System.out.println(exceptionType);
        }
        //运行方法
        //定义方法的调用者
        Student s = new Student();
        //临时取消私有方法的访问权限
        m.setAccessible(true);
        m.invoke(s, "汉堡包");//在吃汉堡包
    }
}

6.反射的作用

①获取一个类里面所有的信息,获取到了之后,再执行其他的业务逻辑
②结合配置文件,动态的创建对象并调用方法

在Java中,反射可以用于获取和操作类的信息,包括类的属性、方法、构造函数等。

  1. 动态获取类的信息:使用反射可以在运行时动态获取类的信息,例如获取类的属性、方法、构造函数等,并可以通过反射来创建类的实例。
  2. 动态创建对象:通过反射可以在运行时动态创建一个类的对象,而无需在编译时提前知道需要创建哪个类的对象。
  3. 调用对象的方法:通过反射可以调用一个类的方法,包括公有方法和私有方法。这使得我们可以在运行时根据需要动态调用不同的方法。
  4. 修改私有属性:通过反射可以修改一个类的私有属性的值,即使这个属性没有提供公开的set方法。
  5. 扩展应用:反射还可以用于实现一些框架和工具,例如注解处理器、对象序列化、单元测试等。
    需要注意的是,反射使用起来较为复杂,在性能上也比直接调用方法要慢。因此,在使用反射时应该谨慎,并在必要的情况下才使用。

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

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

相关文章

WebofScience快速检索文献的办法

Web of Science为什么老是搜不到文章&#xff0c;原来是要在这个地方全部勾选 如果是搜标题的话&#xff0c;选Title&#xff0c;输入你要搜的文章标题 另外&#xff0c;也可以在浏览器直接搜文章标题&#xff0c;得到文章的DOI&#xff0c;然后选DOI&#xff0c;直接搜DOI也行…

2.6 KERNEL LAUNCH

图2.15在vecAdd函数中显示最终主机代码。此源代码完成了图2.6.中的骨架。2.12和2.15共同说明了一个简单的CUDA程序&#xff0c;该程序由主机代码和设备内核组成。该代码是硬接的&#xff0c;每个线程块使用256个线程。然而&#xff0c;使用的线程块的数量取决于向量&#xff08…

如何保证本地缓存的一致性(和分布式缓存)

保证本地缓存和分布式缓存的一致性是一个关键的问题&#xff0c;因为这可以确保系统的健壮性和响应速度。以下是一些在Java中实现这一目标的方法&#xff1a; 1.使用一致性哈希&#xff1a;一致性哈希是一种特殊的哈希技术&#xff0c;它能够在节点增减时最小化哈希环上的数据分…

【大数据进阶第三阶段之Hive学习笔记】Hive常用命令和属性配置

目录 1、Hive安装 2、HiveJDBC访问 2.1、启动hiveserver2服务 2.2、连接hiveserver2服务 2.3、注意 3、Hive常用交互命令 3.1、“-e”不进入hive的交互窗口执行sql语句 3.2、“-f”执行脚本中sql语句 4、Hive其他命令操作 4.1、退出hive窗口 4.2、在hive cli命令窗口…

智慧医院预约及支付平台—智慧支付

医保支付流程 自费支付流程 智慧医院支付业务介绍 社保卡绑定(身份认证) 认证方案:银行身份已验证客户,可通过本人银行登记的手机号码登录医院APP后,在完善APP注册身份信息时,将相关信息发送苏州银行,由银行核对客户身份信息正确性并将社保卡绑定本人手机。核实后的身份…

爬虫实战 - 微博评论数据可视化

简介&#xff1a; 我们都知道在数据比较少的情况下&#xff0c;我们是可以很轻易的获取到数据中的信息。但是当数据比较庞大的时候呢&#xff0c;我们就很难看出来了。尤其是面对现如今数以万计的数据&#xff0c;就更了。 不过好在我们可以通过计算机来帮我们进行分析&#…

【鸿蒙4.0】安装DevEcoStudio

1.下载安装包 HUAWEI DevEco Studio和SDK下载和升级 | HarmonyOS开发者华为鸿蒙DevEco Studio是面向全场景的一站式集成开发环境,&#xff0c;在鸿蒙官网下载或升级操作系统开发工具DevEco Studio最新版本&#xff0c;SDK配置和下载&#xff0c;2.1支持Mac、Windows操作系统。…

八大算法排序@选择排序(C语言版本)

目录 选择排序概念算法思想示例步骤1步骤2步骤...n最后一步 代码实现时间复杂度空间复杂度特性总结 选择排序 概念 选择排序&#xff08;Selection Sort&#xff09;是一种简单直观的排序算法。基本思想是在未排序的序列中找到最小&#xff08;或最大&#xff09;元素&#xf…

[论文阅读] Revisiting Feature Propagation and Aggregation in Polyp Segmentation

[论文地址] [代码] [MICCAI 23] Abstract 息肉的准确分割是筛查过程中有效诊断结直肠癌的关键步骤。 由于能够有效捕获多尺度上下文信息&#xff0c;普遍采用类似UNet 的编码器-解码器框架。 然而&#xff0c;两个主要限制阻碍了网络实现有效的特征传播和聚合。 首先&#xff…

Eslint+Prettier

1.Eslint js验证的规则标准,Vue也有自己的独特的验证规则,vue-eslint-plugin属于vue自己的验证规则。 如果不想报错,可以在package.json/rules里面进行关闭,默认是开启的,默认缩进是两个空格。 2.Prettier - Code formatter 使写代码更加的美观 可选的配置项: 例如: module…

C语言编译器(C语言编程软件)完全攻略(第二十九部分:Linux GCC简明教程(使用GCC编写C语言程序))

介绍常用C语言编译器的安装、配置和使用。 二十九、Linux GCC简明教程&#xff08;使用GCC编写C语言程序&#xff09; 市面上常见的 Linux 都是发行版本&#xff0c;典型的 Linux 发行版包含了 Linux 内核、桌面环境&#xff08;例如 GNOME、KDE、Unity 等&#xff09;和各种…

光速爱购--靠谱的SpringBoot项目

简介 这是一个靠谱的SpringBoot项目实战&#xff0c;名字叫光速爱购。从零开发项目&#xff0c;视频加文档&#xff0c;十天就能学会开发JavaWeb项目。 教程路线是&#xff1a;搭建环境> 安装软件> 创建项目> 添加依赖和配置> 通过表生成代码> 编写Java代码&g…

1018:奇数偶数和1028:I love 闰年!和1029:三角形判定

1018&#xff1a;奇数偶数 要求&#xff1a;输入一个整数&#xff0c;判断该数是奇数还是偶数。如果该数是奇数就输出“odd”&#xff0c;偶数就输出“even”&#xff08;输出不含双引号&#xff09;。 输入样例&#xff1a;8 输出样例&#xff1a;even 程序流程图&#xff1a…

Dockerfile的EXPOSE

文章目录 环境总结测试使用EXPOSE测试1&#xff1a;不做端口映射测试2&#xff1a;-p 8080:80测试3&#xff1a;-P测试4&#xff1a;--networkhost 不使用EXPOSE 参考 环境 RHEL 9.3Docker Community 24.0.7 总结 如果懒得看测试的详细信息&#xff0c;可以直接看结果&#…

算法通关村番外篇-优先队列

大家好我是苏麟 , 今天聊聊优先队列 . 优先队列 我们了解优先队列之前先说说队列 . 队列的特点是什么&#xff1f; 队列的特点是先进先出&#xff08;FIFO&#xff09;。 入队列&#xff0c;将新元素置于队尾&#xff1a; 出队列&#xff0c;队头元素最先被移出&#xff1a…

每周一算法:倍增法查找位置

倍增法 倍增法&#xff08;Binary Lifting&#xff09;&#xff0c;顾名思义&#xff0c;就是利用“以翻倍的速度增长”的思想来解决问题的一类算法&#xff0c;它能够使线性的处理转化为对数级的处理&#xff0c;大大地优化时间复杂度。这个方法在很多算法中均有应用&#xf…

密码学中的Hash函数

目录 一. 介绍 二. hash函数的五个基本性质 &#xff08;&#xff11;&#xff09;压缩性 &#xff08;&#xff12;&#xff09;正向计算简单性 &#xff08;&#xff13;&#xff09;逆向计算困难性 &#xff08;&#xff14;&#xff09;弱无碰撞性 &#xff08;&…

ARMv8-AArch64 的异常处理模型详解之异常等级、执行状态以及安全状态

ARMv8-AArch64 的异常处理模型详解 一&#xff0c;特权和异常等级1.1 异常等级 Exception levels 二&#xff0c;特权的类型2.1 内存特权2.2 访问寄存器的特权 三&#xff0c;执行状态和安全状态3.1 执行状态 Execution states3.2 执行状态切换 3.3 安全状态 Security states3.…

知识图谱之汽车实战案例综述与前瞻分析

知识图谱的前置介绍 什么是知识图谱 知识图谱本质(Knowledge Graph&#xff09;上是一种叫做语义网络(semantic network &#xff09; 的知识库&#xff0c;即具有有向图结构的一个知识库&#xff1b;图的结点代表实体&#xff08;entity&#xff09;或者概念&#xff08;con…

【Python学习】Python学习6-循环语句

目录 【Python学习】【Python学习】Python学习6-循环语句 前言for循环for循环示例通过序列索引迭代循环使用 else 语句 while循环while循环示例continue和 break无限循环循环使用 else 语句简单语句组 嵌套循环Python for 循环嵌套语法&#xff1a;Python while 循环嵌套语法&…