java每日一记 —— 谈谈反射

news2024/11/15 19:38:53

这应该是基础吧

  • 1.先来说点前置知识:类的加载机制
  • 2.以自己的方式来谈反射的概念
  • 3.获取class的三种方式
    • 3.1.通过已知的类型获取class
    • 3.2.通过实例对象获取class
    • 3.3.通过Class.forName获取全路径指定类名的class
  • 4.整理了一下API:坦言说🪡累
  • 5.现场玩一把
  • 6.反射机制应用的场景

本篇代码在jdk11中测试通过

1.先来说点前置知识:类的加载机制

1.博主是这样理解的:Java 类的加载机制就是将类从字节码转换为运行时实例的过程(好吧!!!我是来搞笑的😱😱😱😱)

2.回归正题:Java 类的加载机制是一个动态过程,由 Java 虚拟机 (JVM) 自动完成

一般流程如下:

  • 加载:将类从磁盘或其他数据源加载到 JVM 内存中
  • 验证:确保类有效,并符合语义要求
  • 准备:给类变量分配内存,并设置类变量的默认值
  • 解析:将常量池中的符号引用替换为直接引用
  • 初始化:给类变量赋值,并调用类构造函数

来一张小破图:
在这里插入图片描述

开个小玩笑:我怎么越看越像上高速公路的一个过程??
加载?好像是从四面八方来的车要进入收费站入口
验证?怎么看都是收费站的要判断你是否符合上高速的要求啊?
准备?这个有点像给你发的通行卡中记录了你的信息?
解析?你进入高速匝道后的指示牌给你直接引用到正确的路线?
初始化?这个不就是进入高速后给车加油门,并且打开我们的bgm?

3.总结一下:其实吧每个阶段都涉及 JVM 内部的操作,这只是为了确保类的安全性和可用性。因此,在运行时可以通过反射轻松访问 Java 类的信息

特别注意:今天的主角不是类加载机制,这些只是根据经验写了点

2.以自己的方式来谈反射的概念

1.定义:Java反射是一种允许我们在程序运行时访问和修改其自身行为的技术。它允许我们在运行时检查和修改程序的行为,而不需要重新编译或启动程序

2.面试时我如果按照定义说,面试官肯定肯说我背了八股,所以我用自己的理解说下反射的定义吧:

  • 通俗说法:Java反射是一种能够在运行时检查和修改程序自身行为的能力。它可以让我们在不重新编译或重启应用程序的情况下,对程序的行为进行更改。例如,我们可以使用反射来动态地改变一个类的方法或者字段值,或者动态地创建和访问类的实例

我来以生活的方式来说:

首先,让我们从一个简单的例子开始。假设我们正在准备一顿晚餐,并且想要制作一道美味的意大利面。在烹饪过程中,我们需要了解各种食材的特性,比如面条需要煮多久才能达到最佳口感,番茄酱应该如何调配等等。这就像是我们在编程时需要了解每个类和方法的功能一样。

现在,想象一下如果我们有一本食谱,它不仅告诉我们如何做菜,还告诉我们可以用哪些不同的食材来替代原本的食材,甚至还可以告诉我们每种食材有哪些未知的特性和用途。这就是Java反射的概念

Java反射允许我们在运行时检查和修改程序的行为。就像我们的食谱一样,它提供了一种方式来查看和操作代码的各种元素,如类、接口、字段和方法。我们可以利用这些信息来创建新的对象、调用方法、改变字段值等

3.new 和反射的对比

在这里插入图片描述
4.java相关类介绍

类名描述
Class<T>代表类的实体,在运行的Java应用程序中表示类或者接口
Field类的成员变量(成员变量也称为类的属性)
Method类的方法
Constructor<T>类的构造方法

3.获取class的三种方式

3.1.通过已知的类型获取class

1.上代码

public Class<User> getUser01(){
    Class<User> clazz = User.class;
    return clazz;
}

2.运行结果
在这里插入图片描述

3.2.通过实例对象获取class

1.上代码

public Class<User> getUser02(){
    User user = new User();
    Class<?> clazz = user.getClass();
    return (Class<User>)clazz;
}

2.运行结果
在这里插入图片描述

3.3.通过Class.forName获取全路径指定类名的class

1.上代码

public static Class<User> getUser03()throws ClassNotFoundException{
    Class<?> clazz = Class.forName("com.andy.fan_she.pojo.User");
    return (Class<User>)clazz;
}

2.运行结果
在这里插入图片描述

4.整理了一下API:坦言说🪡累

1.Class常用操作方法

// 获取所有的构造方法 (private和public都可以)
public Constructor<?>[] getDeclaredConstructors()

// 获取特定的构造方法 (private和public都可以)
public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes)
   
// 获取类的父类
public native Class<? super T> getSuperclass()

// 获取类实现的接口
private Class<?>[] getInterfaces(boolean cloneArray)

// 获取在类内定义的内部类或接口
public Class<?>[] getDeclaredClasses()

// 获取所有的方法
public Method[] getDeclaredMethods() throws SecurityException

// 根据方法名和参数获得特定的方法
public Method getDeclaredMethod(String name, Class<?>... parameterTypes)

// 获取类型的定义的所有属性
public Field[] getFields()

// 根据属性命名获得特定的Field
public Field getField(String name)

2.Method常用的操作方法

// 获得方法的放回类型
public Class<?> getReturnType()

// 获得方法的传入参数类型
public Class<?>[] getParameterTypes()

// obj是实例对象,args是方法,反过来由Method控制对象的方法调用
public Object invoke(Object obj, Object... args)

3.Field常用的操作方法

// 属性与obj相等则返回true
public boolean equals(Object obj)

// 获得obj中对应的属性值
public Object get(Object obj)

// 设置obj中对应属性值
public void set(Object obj, Object value)

4.Constructor

// 根据传递的参数创建类的对象:initargs 构造方法参数
public T newInstance(Object... initargs) 

⚠️注意啦!!!注意啦!!!⚠️

  • 从Java 11开始,newInstance()方法已被弃用,因为它存在一定的安全风险。现在推荐使用Class.getDeclaredConstructor().newInstance()的方式来替代

  • 在Java 11及更高版本中,如果没有显式声明默认构造函数,那么默认情况下是不会生成无参数构造函数的。因此,如果要调用newInstance()方法,则需要确保类具有可访问的无参数构造函数

5.现场玩一把

来个测试对象类

/**
 * @author Andy
 * @version 0.0.1
 */
public class User implements Serializable {

    private Integer id;

    private String username;
    
	private string password;

    private String password;
    
    public User(Integer id, String username, String password) {
        this.id = id;
        this.username = username;
        this.password = password;
    }

    ...getter/setter

}

1.根据class创建对象

public User getUser01() throws Exception {
	Class<User> clazz = User.class;
    Constructor<User> constructor = clazz.getConstructor(Integer.class, String.class, String.class);
    constructor.setAccessible(true);
    User user = constructor.newInstance(1, "andy", "123456");
    return user;
}

2.由class获取Field,并操作实例的属性

public static User getUser02() throws Exception{
    Class<User> clazz = User.class;
    Constructor<User> constructor = clazz.getConstructor(Integer.class, String.class, String.class);
    constructor.setAccessible(true);
    User user = constructor.newInstance(1, "andy", "123456");
    // 主要是这块逻辑
    Field declaredField = clazz.getDeclaredField("id");
    declaredField.setAccessible(true);
    declaredField.set(user, 2);
    return user;
}

3.由class获取Method,并反射调用实例方法

// 在pojo中加入:
public void getTestUser(String name){
    System.out.println("测试反射方法:" + name);
}

// 测试方法:
public static void getUser03() throws Exception {
    Class<User> clazz = User.class;
    Constructor<User> constructor = clazz.getConstructor(Integer.class, String.class, String.class);
    constructor.setAccessible(true);
    User user = constructor.newInstance(1, "andy", "123456");
    //主要逻辑
    Method declaredMethod = clazz.getDeclaredMethod("getTestUser", String.class);
    declaredMethod.setAccessible(true);
    declaredMethod.invoke(user, "Andy测试");
}

6.反射机制应用的场景

  • 动态拓展:假设有同一组类是实现相同的接口,并且类的加载方式不限制。当我们需要那种具体类实现的功能时,只需加载.class文件,并获取对应的Class对象。可以由Class或者Constructor实例化对象instance;根据接口定义,可以获取Class里的某一方法Method,并配合instance反射调用功能方法
  • Spring的IOC就是基于反射机制实现
  • JDK的动态代理

博主记得之前写过一个动态代理的博客,今天特地的跑去看了下🪡的是反射机制。有兴趣的可以看下:https://blog.csdn.net/weixin_44702984/article/details/130278266?spm=1001.2014.3001.5502

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

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

相关文章

【腾讯云云上实验室-向量数据库】TAI时代的数据枢纽-向量数据库 VectorDB

一、向量数据库的发展历程和时代机遇 回顾向量数据库的发展历程&#xff1a; 2012年开始&#xff0c;深度神经网络的发展催生了向量数据库的发展&#xff1b;2015年至2016年&#xff0c;Google和微软发布了标志性的论文&#xff1b;2017年&#xff0c;Facebook开源了Faiss框架…

【具身智能评估1】具身视觉语言规划(EVLP)仿真环境汇总

参考论文&#xff1a;Core Challenges in Embodied Vision-Language Planning 论文作者&#xff1a;Jonathan Francis, Nariaki Kitamura, Felix Labelle, Xiaopeng Lu, Ingrid Navarro, Jean Oh 论文原文&#xff1a;https://arxiv.org/abs/2106.13948 论文出处&#xff1a;Jo…

文心一言-情感关怀之旅

如何让LLM更有温度。 应用介绍

猜数字优化版(带进度条)

其实就是加了个动态进度条显示加载游戏的流程&#xff0c;这样看上去是不是更有big了hhhh #include<windows.h> #include<iostream> #include<ctime> using namespace std; void menu() {printf("1.开始游戏\n");printf("0.退出游戏\n")…

PP-YOLOE: An evolved version of YOLO(2022.12)

文章目录 Abstract1. Introduction2. Method2.1. A Brief Review of PP-YOLOv22.2. Improvement of PP-YOLOEAnchor-freeBackbone and NeckTask Alignment Learning (TAL)Efficient Task-aligned Head (ET-head) 3.Experiment4. Conclusion 原文链接 源代码 Abstract 在本报告…

恕我直言,大模型对齐可能无法解决安全问题,我们都被表象误导了

是否听说过“伪对齐”这一概念&#xff1f; 在大型语言模型&#xff08;LLM&#xff09;的评估中&#xff0c;研究者发现了一个引人注目的现象&#xff1a;当面对多项选择题和开放式问题时&#xff0c;模型的表现存在显著差异。这一差异根源在于模型对复杂概念的理解不够全面&…

Python hashlib 模块详细教程:安全哈希与数据完整性保护

更多Python学习内容&#xff1a;ipengtao.com 大家好&#xff0c;我是涛哥&#xff0c;今天为大家分享 Python hashlib 模块详细教程&#xff0c;文章6500字&#xff0c;阅读大约17分钟&#xff0c;大家enjoy~~ hashlib模块为Python提供了一种简便的方式来使用各种哈希算法&…

ACM练习——第五天

还有两天就要比赛了&#xff0c;进入正题吧 题目一&#xff1a;小红的签到题 小红的签到题 (nowcoder.com) 这道题也就是热身水平&#xff0c;机会很清楚的发现只需要c/a就可以得出答案了 参考代码&#xff1a; #include <iostream>using namespace std;int main(){int a…

SecureCRT的“New line mode“

New line mode选中与不选中啥区别 在SecureCRT中&#xff0c;"New line mode"是一个关键配置项&#xff0c;主要用于解决不同操作系统之间的换行问题。当不选中"New line mode"时&#xff0c;SecureCRT会将接收到的数据按照原样发送&#xff0c;不会对数据…

腾讯智影数字人工具

腾讯智影数字人工具 腾讯智影数字人的形象风格多样&#xff0c;包括写实、卡通等&#xff0c;可以满足不同年龄层观众的喜好。同时&#xff0c;腾讯智影数字人也提供了灵活的驱动方案&#xff0c;可以通过文本或配音直接生成视频&#xff0c;并支持数字人做出与视频一样的动作…

计算机网络——WLAN简解

1. WLAN的发展历程 ❓ WLAN和WIFI有什么区别。 &#x1f604; 具体来说&#xff0c;WALN是抽象的概念&#xff0c;代表这无线局域网这一类技术&#xff0c;而WIFI则是具体的具体技术标准&#xff0c;虽然在生活中&#xff0c;二者的表现是强相关的&#xff08;因为是使用的wifi…

talbay---贝叶斯网络分析工具产品介绍

一 简介 talbay是拥有独立知识产权的国产软件&#xff0c;主要功能是贝叶斯网络建模、决策网络建模、概率计算、决策支持、敏感性分析、网络模型验证、机器学习等。talbay以用户为中心&#xff0c;简单易用, 计算准确高效&#xff0c;分析全面多样&#xff0c;在应用成熟理论及…

基础模型的自然语言处理能力综述

NLP作为一个领域为基础模型开辟了道路。虽然这些模型在标准基准测试中占据主导地位&#xff0c;但这些模型目前获得的能力与那些将语言描述为人类交流和思维的复杂系统的能力之间存在明显的差距。针对这一点&#xff0c;我们强调语言变异的全部范围&#xff08;例如&#xff0c…

西南科技大学814考研一

C语言基础 字节大小 char&#xff1a;1 字节 unsigned char&#xff1a;1 字节 short&#xff1a;2 字节 unsigned short&#xff1a;2 字节 int&#xff1a;通常为 4 字节&#xff08;32 位平台&#xff09;或 8 字节&#xff08;64 位平台&#xff09; unsigned int&#x…

汽车音响静音检测电路芯片D3703F,适用于汽车音响系统,采用封装形式SOP8

D3703F是-块汽车音响静音检测电路。用于音响系统检测在放音或快进/退时进行静音检测。D3703F的电压范围: 6V~16V&#xff0c; 信号检测和静音时间可通过外围电阻、电容来改变。 主要特点&#xff1a; ● 快进退时也可进行静音检测 ● 信号检测和静音时间可通过外围元件值来改…

机器学习笔记 - 使用 PyTorch 的多任务学习和 HydraNet

一、HydraNet简述 特斯拉使用了一个模型可以解决他们正在处理的每一项可能的任务。 例如:物体检测、道路曲线估计、深度估计、3D重建、视频分析、物体追踪、ETC等等。 以下是在 NVIDIA GPU 上以 3 种不同配置运行的 2 个计算机视觉模型的基准测试。 在第一个配置中,我…

贝叶斯AB测试

AB测试是用来评估变更效果的有效方法&#xff0c;但很多时候会运行大量AB测试&#xff0c;如果能够在测试中复用之前测试的结果&#xff0c;将有效提升AB测试的效率和有效性。原文: Bayesian AB Testing[1] 随机实验&#xff0c;又称AB测试&#xff0c;是行业中评估因果效应的既…

iframe父子页面通信相互调用传递参数多个postMessage

效果 如何运行 父页面代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title>…

再也不用担心忘记密码了!如何在Windows 10或11中重置被遗忘的密码

​如果你忘记了Windows电脑的密码,不要惊慌。Windows 10和Windows 11都允许你重置忘记的密码,无论你使用的是Microsoft帐户还是本地帐户。你所要做的就是回答你的安全问题以重置密码。另一种选择是创建一个密码重置盘,你可以在任何U盘上进行。 除了使用密码之外,你还应该启…

CCF ChinaSoft 2023 论坛巡礼|软件测试产教研融合论坛

2023年CCF中国软件大会&#xff08;CCF ChinaSoft 2023&#xff09;由CCF主办&#xff0c;CCF系统软件专委会、形式化方法专委会、软件工程专委会以及复旦大学联合承办&#xff0c;将于2023年12月1-3日在上海国际会议中心举行。 本次大会主题是“智能化软件创新推动数字经济与社…