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); // 获取数组元素
相关推荐
Theodore_10222 小时前
4 设计模式原则之接口隔离原则
java·开发语言·设计模式·java-ee·接口隔离原则·javaee
冰帝海岸3 小时前
01-spring security认证笔记
java·笔记·spring
世间万物皆对象3 小时前
Spring Boot核心概念:日志管理
java·spring boot·单元测试
没书读了4 小时前
ssm框架-spring-spring声明式事务
java·数据库·spring
小二·4 小时前
java基础面试题笔记(基础篇)
java·笔记·python
开心工作室_kaic4 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端
懒洋洋大魔王4 小时前
RocketMQ的使⽤
java·rocketmq·java-rocketmq
武子康4 小时前
Java-06 深入浅出 MyBatis - 一对一模型 SqlMapConfig 与 Mapper 详细讲解测试
java·开发语言·数据仓库·sql·mybatis·springboot·springcloud
转世成为计算机大神5 小时前
易考八股文之Java中的设计模式?
java·开发语言·设计模式
qq_327342735 小时前
Java实现离线身份证号码OCR识别
java·开发语言