Java反射机制的详细讲解

news2024/12/27 13:09:03

目录

1.反射机制是什么?

2.反射机制能干什么?

3.反射相关的类

​编辑

4.Class类(反射机制的起源 )

5.反射机制相关的API

1.(重要)常用获得类相关的方法

2.常用获得类中属性相关的方法(以下方法返回值为Field相关

3.(了解)获得类中注解相关的方法

4.(重要)获得类中构造器相关的方法(以下方法返回值为Constructor相关)

​编辑 5.(重要)获得类中方法相关的方法(以下方法返回值为Method相关)

6.反射示例

1.获得Class对象的三种方式

 2.反射的使用

1.产生对象

方法一:调用类的无参构造,且该构造方法必须是public权限!!

 方法二:通过Constructer类来调用构造方法产生对象

2.通过反射操作类中的方法

7、反射优点和缺点


1.反射机制是什么?

Java反射是指在程序运行期间,可以动态的获取到任意一个类的相关信息,并且调用任意对象的属性或方法,这种动态获取类的信息的方式和动态调用对象方法的功能称之为Java对象的反射机制

Java文件被编译后,生成了.class文件,JVM此时就要去解读.class文件 ,被编译后的Java文件.class也被JVM解析为一个对象,这个对象就是 java.lang.Class .这样当程序在运行时,每个java文件就最终变成了Class类对象的一个实例。我们通过Java的反射机制应用到这个实例,就可以去获得甚至去添加改变这个类的属性和动作,使得这个类成为一个动态的类

2.反射机制能干什么?

通过Java语言中的反射机制可以操作字节码文件,还可以操作代码片段(class文件)

Java反射机制的相关类都在Java.long.reflect.*;包下

3.反射相关的类

4.Class(反射机制的起源 )

Java文件被编译后,生成了.class文件,JVM此时就要去解读.class文件 ,被编译后的Java文件.class也被JVM解析为 一个对象,这个对象就是 java.lang.Class .这样当程序在运行时,每个java文件就最终变成了Class类对象的一个实 例。我们通过Java的反射机制应用到这个实例,就可以去获得甚至去添加改变这个类的属性和动作,使得这个类成 为一个动态的类 .

5.反射机制相关的API

1.(重要)常用获得类相关的方法

2.常用获得类中属性相关的方法(以下方法返回值为Field相关

  • getField(String name) :获得某个公有的属性对象
  • getFields() :获得所有公有的属性对象
  • getDeclaredField(String name) :获得某个属性对象
  • getDeclaredFields() :获得所有属性对象

3.(了解)获得类中注解相关的方法

4.(重要)获得类中构造器相关的方法(以下方法返回值为Constructor相关

 5.(重要)获得类中方法相关的方法(以下方法返回值为Method相关

  • getMethod(String name, Class...<?> parameterTypes) :获得该类某个公有的方法
  • getMethods() :获得该类所有公有的方法
  • getDeclaredMethod(String name, Class...<?> parameterTypes) :获得该类某个方法
  • getDeclaredMethods() :获得该类所有方法

6.反射示例

1.获得Class对象的三种方式

在反射之前,我们需要做的第一步就是先拿到当前需要反射的类的Class对象,然后通过Class对象的核心方法,达到反射的目的,即:在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性,既然能拿到那么,我们就可以修改部分类型信息。
第一种 ,使用 Class.forName(" 类的全路径名 "); 静态方法。
前提:已明确类的全路径名。
第二种 ,使用  类名称.class 方法。
说明:仅适合在编译前就已经明确要操作的 Class
第三种 ,使用类任意对象的 getClass() 方法
package com.example.reflect.model;

public class Student {
    // 共有属性name
    private String name;
    // 私有属性age
    private Integer age;

    // 不带参数的构造方法
    public Student() {
    }

    // 带参数的构造方法
    private Student(String name, Integer age) {
        this.name = name;
        this.age = age;
        System.out.println("Student(String,name)");
    }

    private void eat(){
        System.out.println("i am eat");
    }
    public void sleep(){
        System.out.println("i am pig");
    }
    private void function(String str) {
        System.out.println(str);
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
class TeatReflect {
    public static void main(String[] args) {
        /**
         * 1.通过getClass获取Class对象
         */
        Student student = new Student();
        Class c = student.getClass();
        /**
         * 2.直接通过 类名.class 的方式得到,该方法最为安全可靠,程序性能更高
         * 这说明任何一个类都有一个隐含的静态成员变量 class
         */
        Class c2 = Student.class;
        /**
         * 3、通过 Class 对象的 forName() 静态方法来获取,用的最多,
         * 但可能抛出 ClassNotFoundException 异常
         */
        Class c3 = null;
        try {
            c3 = Class.forName("com.example.reflect.model.Student");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        //一个类在 JVM 中只会有一个 Class 实例,即我们对上面获取的
        //c1,c2,c3进行 equals 比较,发现都是true
        System.out.println(c.equals(c2));
        System.out.println(c3.equals(c2));
        System.out.println(c3.equals(c));
    }
}

 2.反射的使用

1.产生对象

方法一:调用类的无参构造,且该构造方法必须是public权限!!

 // 产生对象
    public static void reflectNewInstance() {
        try {
            Class<?> classStudent = Class.forName("com.example.reflect.model.Student");
            // 调用的是无参构造,且必须是公有的
            Object objectStudent = classStudent.newInstance();
            Student student = (Student) objectStudent;
            System.out.println("获得学生对象:"+student);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

如果使私有的无参构造那么就会报错了,就像下面这样:

此时我们通过无参构造去获取对象:

 方法二:通过Constructer类来调用构造方法产生对象

Constructer类就是Java中利用反射操作构造方法的类

  • getConstructor(参数):获取该类的所有public 权限的构造方法
  • getDeclareConstructor:获取该类的所有权限的构造方法,包括私有权限
    // 产生对象
    public static void reflectNewInstance2() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        // 获取Class对象
        Class<Student> classStudent = Student.class;
        // 获得所有的构造方法
        Constructor<Student>[] constructors = (Constructor<Student>[]) classStudent.getDeclaredConstructors();
        System.out.println(Arrays.toString(constructors));
        // 获取私有的有参构造
        Constructor<Student> constructor = classStudent.getDeclaredConstructor(String.class,Integer.class);
        // 破坏封装性·
        constructor.setAccessible(true);
        // 通过私有构造方法创建对象
        Student student = constructor.newInstance("锦鲤",18);
        System.out.println(student);
    }

反射可以获得所有的不论公有私有的方法和属性,他会破坏封装性,只在当前JVM进程中可见

2.通过反射操作类中的方法

    // 操作方法
    public static void reflectByMethod() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        // 获取Class对象
        Class<Student> classStudent = Student.class;
        Method[] methods = classStudent.getDeclaredMethods();
        System.out.println(Arrays.toString(methods));
        // 通过反射来调用普通方法和静态方法
        // 调用普通方法首先要产生对象
        Student student = classStudent.newInstance();
        // 通过反射拿到fun方法的反射方法
        Method methodFun = classStudent.getMethod("fun", String.class);
        // 通过Method反射对象调用fun方法, 传入调用该方法的对象以及需要传入的参数
        methodFun.invoke(student, "锦鲤");
        // 调用静态方法
        Method methodTest = classStudent.getMethod("test");
        methodTest.invoke(null);
    }

7、反射优点和缺点

优点:
  • 1. 对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法
  • 2. 增加程序的灵活性和扩展性,降低耦合性,提高自适应能力
  • 3. 反射已经运用在了很多流行框架如:StrutsHibernateSpring 等等。
缺点:
  • 1. 使用反射会有效率问题。会导致程序效率降低。具体参考这里:http://www.imooc.com/article/293679
  • 2. 反射技术绕过了源代码的技术,因而会带来维护问题。反射代码比相应的直接代码更复杂 

反射的讲解就到这里啦!

下篇博客见~ 

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

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

相关文章

iOS开发-实现3DTouch按压App快捷选项shortcutItems及跳转功能

iOS开发-实现3DTouch按压App快捷选项shortcutItems及跳转功能 App的应用图标通过3D Touch按压App图标&#xff0c;会显示快捷选项&#xff0c;点击选项可快速进入到App的特定页面。 这里用到了UIApplicationShortcutItem与UIMutableApplicationShortcutItem 一、效果图 这里…

VS附加到进程调试

操作&#xff1a; 要附加到进程中调试外部可执行文件&#xff0c;您需要使用Visual Studio的“调试附加”功能。以下是附加到进程中调试外部可执行文件的步骤&#xff1a; 打开您要调试的源代码文件或可执行文件。打开Visual Studio。选择“调试”菜单&#xff0c;然后选择“…

三种无监督学习方法用于肿瘤病理图像预测任务

这里写自定义目录标题 BYOLBYOL描述基本思路示意图合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个注脚注释也是必…

大数据_Hadoop_Parquet数据格式详解

之前有面试官问到了parquet的数据格式&#xff0c;下面对这种格式做一个详细的解读。 参考链接 &#xff1a; 列存储格式Parquet浅析 - 简书 Parquet 文件结构与优势_parquet文件_KK架构的博客-CSDN博客 Parquet文件格式解析_parquet.block.size_davidfantasy的博客-CSDN博…

day16 | 513.找树左下角的值 112.路径总和 106.从中序与后序遍历序列构造二叉树

文章目录 一、找树左下角的值二、路径总和三、从中序与后序遍历序列构造二叉树 一、找树左下角的值 513.找树左下角的值 暴力解法 class Solution { public:int findBottomLeftValue(TreeNode *root){// 第一眼想到的就是层序遍历&#xff0c;取最后一层的第一个值即可queue…

Vue系列第六篇:axios封装,登录逻辑优化,404页面实现,Go语言跨域处理

第五篇利用vue实现了登录页面&#xff0c;用go语言开发了服务端并最后在nginx上进行了部署。本篇将axios封装&#xff0c;登录逻辑优化&#xff0c;404页面实现。 目录 1.前端 1.1代码结构 1.2源码 2.服务端 2.1源码 3.运行效果 4.注意事项 4.1webpack.config.js和vue…

探索自除数:发现区间内的神奇数字

本篇博客会讲解力扣“728. 自除数”的解题思路&#xff0c;这是题目链接。 对于给定的正整数num&#xff0c;我们如何判断它是不是自除数呢&#xff1f;根据定义&#xff0c;我们只需要把num的每一位数字都取出来&#xff0c;判断能不能整除num&#xff0c;如果发现num的某一位…

【虹科案例】使用虹科模块化数字化仪进行车辆测试

引言 模块化仪器比传统仪器的尺寸大大减小&#xff0c;适合安装在电路卡上&#xff0c;同时也可以将多个卡插入具有通用计算机接口、电源和互连的框架中。模块化仪器框架包括使用标准 PCIe 接口的计算机、PXI 测试框架或基于 LXI 的盒子&#xff0c;工程师通常会使用多个卡并将…

git stash clear清空本地暂存代码

git stash clear清空本地暂存代码 git stash 或者 git stash list 查看本地暂存的代码。 清除本地暂存的代码修改&#xff1a; git stash clear git回退代码仓库版本_git回退到之前的版本会影响本地代码嘛_zhangphil的博客-CSDN博客git回退代码版本_git回退到之前的版本会影…

基于opencv的几种图像滤波

一、介绍 盒式滤波、均值滤波、高斯滤波、中值滤波、双边滤波、导向滤波。 boxFilter() blur() GaussianBlur() medianBlur() bilateralFilter() 二、代码 #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> …

01 制作Windows11启动盘及安装 || 包含校验ISO映像的方法

前言 由于空间越来越不够用了&#xff0c;上次为Ubuntu分配了96G的空间依然是快要被用完&#xff0c;连一个数据集都放不下了&#xff0c;因此我不得不选择换硬盘。 由于是离谱的华为Mate book D 15的2021款逆天机型&#xff0c;我没有第二个硬盘位。至于说移动硬盘的解决方案…

python3GUI--我的翻译器By:PyQt5(附下载地址)

文章目录 一&#xff0e;前言二&#xff0e;展示1.主界面2.段落翻译3.单词翻译 三&#xff0e;设计1.UI设计2.软件设计3.参考 四&#xff0e;总结 一&#xff0e;前言 很早之前写过一篇python3GUI–翻译器By:PyQt5&#xff08;附源码&#xff09; &#xff0c;但是发现相关引擎…

LED显示屏技术:数码时代的绚丽舞台

随着信息技术的飞速发展&#xff0c;LED显示屏技术成为现代社会不可或缺的一部分。这种技术以其高亮度、高清晰度和多样化的应用领域&#xff0c;在数字化时代展现出绚丽多彩的画面&#xff0c;为我们带来了前所未有的视觉体验。本文将探讨LED显示屏技术的原理、应用以及对于现…

【JavaEE】简单了解JVM

目录 一、JVM中的内存区域划分 二、JVM的类加载机制 1、类加载的触发时机 2、双亲委派模型 1.1、向上委派 1.2、向下委派 三、JVM中的垃圾回收机制&#xff08;GC&#xff09; 1、确认垃圾 1.1、引用计数&#xff08;Java实际上没有使用这个方案&#xff0c;但是Pytho…

超详细 | 模拟退火算法及其MATLAB实现

模拟退火算法(simulated annealing&#xff0c;SA)是20世纪80年代初期发展起来的一种求解大规模组合优化问题的随机性方法。它以优化问题的求解与物理系统退火过程的相似性为基础&#xff0c;利用Metropolis算法并适当地控制温度的下降过程实现模拟退火&#xff0c;从而达到求解…

RK3588平台开发系列讲解(调试篇)如何进行性能分析

文章目录 一、什么是性能分析呢?二、系统级工具三、源码级工具沉淀、分享、成长,让自己和他人都能有所收获!😄 📢 本篇将介绍性能分析(Performance Profiling) 最简单的性能分析工具是 top,可以快速查看进程的 CPU、内存使用情况;pstack 和 strace 能够显示进程在用…

大数据面试题:HBase的RegionServer宕机以后怎么恢复的?

面试题来源&#xff1a; 《大数据面试题 V4.0》 大数据面试题V3.0&#xff0c;523道题&#xff0c;679页&#xff0c;46w字 可回答&#xff1a;1&#xff09;HBase一个节点宕机了怎么办&#xff1b;2&#xff09;HBase故障恢复 参考答案&#xff1a; 1、HBase常见故障 导…

简要介绍 | 解析模态之间的联系:跨模态学习与多模态学习的区别和联系

注1&#xff1a;本文系“简要介绍”系列之一&#xff0c;仅从概念上对跨模态学习和多模态学习进行非常简要的介绍&#xff0c;不适合用于深入和详细的了解。 解析模态之间的联系&#xff1a;跨模态学习与多模态学习的区别和联系 在人工智能的广泛领域中&#xff0c;跨模态学习…

森林中的兔子(力扣)数学思维 JAVA

森林中有未知数量的兔子。提问其中若干只兔子 “还有多少只兔子与你&#xff08;指被提问的兔子&#xff09;颜色相同?” &#xff0c;将答案收集到一个整数数组 answers 中&#xff0c;其中 answers[i] 是第 i 只兔子的回答。 给你数组 answers &#xff0c;返回森林中兔子的…

Python自动化办公-文件整理脚本

哈喽大家好&#xff0c;今天给大家介绍python自动化办公-文件整理脚本 今天讲解文件整理脚本的实现过程。这是一个很有用的技能&#xff0c;可以帮助你管理你的电脑上的各种文件。需求如下&#xff1a; 需求内容&#xff1a;给定一个打算整理的文件夹目录&#xff0c;这个脚本…