Java反射笔记(自用)

文章目录

  • 一.java程序编译运行过程
      • [1. Java源代码](#1. Java源代码)
      • [2. 编译器](#2. 编译器)
      • [3. JVM可执行的字节码](#3. JVM可执行的字节码)
      • [4. JVM中的解释器](#4. JVM中的解释器)
      • [5. 机器可执行的二进制机器码](#5. 机器可执行的二进制机器码)
      • [6. 程序运行](#6. 程序运行)
  • 二.什么是反射
  • 三.反射的使用
      • [1. 获取Class对象](#1. 获取Class对象)
      • [2. 创建对象实例](#2. 创建对象实例)
      • [3. 访问字段](#3. 访问字段)
      • [4. 调用方法](#4. 调用方法)
      • [5. 操作数组](#5. 操作数组)

一.java程序编译运行过程

java源代码 - - - 编译器 - - - jvm可执行的字节码 - - - jvm中的解释器 - - - 机器可执行的二进制机器码 - - - 程序运行

1. Java源代码

  • 编写 :开发者使用Java语言编写源代码,保存在以.java为扩展名的文件中。

2. 编译器

  • 编译 :Java编译器(如javac)将.java文件中的源代码编译成Java字节码。这一步涉及语法分析、语义检查、生成中间表示和最后生成字节码。
  • 输出 :编译器生成的输出是.class文件,其中包含与源代码对应的字节码。

3. JVM可执行的字节码

  • 字节码:字节码是一种介于源代码和机器码之间的中间形式,设计为可以在任何实现了Java虚拟机的平台上运行。

4. JVM中的解释器

  • 加载 :当运行Java程序时,JVM的类加载器负责将.class文件加载到内存中。
  • 连接:在连接阶段,JVM执行验证、准备和解析步骤,确保代码的安全性和正确性。
  • 初始化:在此阶段,JVM处理静态变量和静态块,执行类构造器。

5. 机器可执行的二进制机器码

  • 解释执行:JVM的解释器逐条解释执行字节码,将其翻译成可以在特定硬件上执行的机器指令。这是一个逐步的过程,每次解释一条字节码指令。
  • 即时编译(JIT编译):为了提高性能,热点代码(即执行次数较多的代码)会被JVM中的即时编译器编译成本地机器码,这样可以直接由硬件执行,无需再进行逐条解释,从而提高执行效率。

6. 程序运行

  • 执行:经过上述所有转换和处理后,程序最终在计算机硬件上运行,用户可以看到程序执行结果。

二.什么是反射

官方定义: 反射(Reflection)是一个强大的机制,它允许程序在运行时查询和操作对象的类信息。使用反射API,可以动态地创建对象、调用方法、访问字段(即便它们被定义为私有的),并且能够加载类。

1.反射与字节码的关系

字节码是java源代码经过javac编译器编译后的中间文件表现形式,即.class里面的内容,这些字节码可以当作jvm的执行的指令集。

而反射是一种在运行时检查或修改程序行为的机制。它以字节码为基础,就是它会首先创建一个Class对象,这个对象能够从字节码中读取类信息,即构造函数,方法,字段这些,私有的也可以访问到,所以具有动态操作的优点和破坏封装性的缺点.

2.Class对象工作流程

  1. 类加载 :JVM首次引用某个类时,它将加载该类的字节码,解析字节码中的元数据,并为这个类创建一个Class类型的对象。

  2. 信息访问 :通过这个Class对象,可以访问类的各种信息:

    • 获取字段(Field):可以检索类中声明的所有字段,无论它们的访问权限如何。
    • 获取方法(Method):可以获取类定义的所有方法。
    • 获取构造器(Constructor):可以访问类的所有构造方法。
    • 获取超类和接口:可以查看类的父类和实现的接口。
  3. 创建实例 :可以使用Class对象来创建其表示的类的实例。这通常通过调用newInstance()方法实现,或者通过获取适当的构造器对象并调用其newInstance()方法。

  4. 动态操作:可以动态调用方法或访问字段,这在编译时是未知的,所以不需要指定特殊类。

三.反射的使用

1. 获取Class对象

java 复制代码
Class<?> clazz1 = Class.forName("java.util.ArrayList"); // 通过类的全限定名

Class<?> clazz2 = ArrayList.class; // 通过类字面量

ArrayList<String> arrayList = new ArrayList<>();
Class<?> clazz3 = arrayList.getClass(); // 通过对象实例调用getClass()

2. 创建对象实例

java 复制代码
Class<?> clazz = Class.forName("java.util.ArrayList");
Object arrayList = clazz.getDeclaredConstructor().newInstance(); // 创建对象实例

3. 访问字段

java 复制代码
Class<?> clazz = Class.forName("com.example.MyClass");
Field field = clazz.getDeclaredField("myField"); // 获取指定字段
field.setAccessible(true); // 设置可访问性,对于私有字段非常重要
Object fieldValue = field.get(instance); // 读取字段值
field.set(instance, "new value"); // 设置新的字段值

4. 调用方法

java 复制代码
Class<?> clazz = Class.forName("com.example.MyClass");
Method method = clazz.getDeclaredMethod("myMethod", String.class); // 获取方法
method.setAccessible(true); // 对于私有方法必须这么做
Object result = method.invoke(instance, "parameter"); // 调用方法

5. 操作数组

java 复制代码
int[] intArray = (int[]) Array.newInstance(int.class, 3); // 创建一个整型数组
Array.set(intArray, 0, 123); // 设置数组元素
int value = Array.getInt(intArray, 0); // 获取数组元素
相关推荐
百事老饼干几秒前
Java[面试题]-真实面试
java·开发语言·面试
customer088 分钟前
【开源免费】基于SpringBoot+Vue.JS医院管理系统(JAVA毕业设计)
java·vue.js·spring boot·后端·spring cloud·开源·intellij-idea
霍格沃兹测试开发学社测试人社区16 分钟前
软件测试学习笔记丨Flask操作数据库-数据库和表的管理
软件测试·笔记·测试开发·学习·flask
2402_8575893618 分钟前
SpringBoot框架:作业管理技术新解
java·spring boot·后端
HBryce2422 分钟前
缓存-基础概念
java·缓存
一只爱打拳的程序猿36 分钟前
【Spring】更加简单的将对象存入Spring中并使用
java·后端·spring
幸运超级加倍~37 分钟前
软件设计师-上午题-16 算法(4-5分)
笔记·算法
杨荧38 分钟前
【JAVA毕业设计】基于Vue和SpringBoot的服装商城系统学科竞赛管理系统
java·开发语言·vue.js·spring boot·spring cloud·java-ee·kafka
minDuck40 分钟前
ruoyi-vue集成tianai-captcha验证码
java·前端·vue.js