【Java】Java 的反射机制(一):反射概述
Java 的反射机制(一):反射概述
- 1.反射概述
- 1.1 静态语言 / 动态语言
- 1.1.1 动态语言
- 1.1.2 静态语言
- 1.2 Java Reflection
- 1.3 Java 反射机制提供的功能
- 1.4 反射的优点和缺陷
- 1.5 反射相关的主要 API
- 1.6 代码示例
- 2.Class 类
- 2.1 什么是 Class 类
- 2.2 Class 类的常用方法
- 2.3 获取 Class 类
- 3.4 哪些类型可以有 Class 对象
1.反射概述
1.1 静态语言 / 动态语言
1.1.1 动态语言
- 是一类在 运行时 可以改变其结构的语言:例如新的函数、对象、甚至代码可以被引进,已有的函数可以被删除或是其他结构上的变化。通俗点说就是在 运行时 代码可以根据某些条件改变自身结构。
- 主要动态语言:Object-C、C#、JavaScript、PHP、Python 等。
1.1.2 静态语言
- 与动态语言相对应的,运行时结构不可变的语言就是静态语言,如 Java、C、C++。
- Java 不是动态语言,但 Java 可以称之为 “准动态语言”。即 Java 有一定的动态性,我们可以利用 反射机制 获得类似动态语言的特性。Java 的动态性让编程的时候更加灵活。
1.2 Java Reflection
反射(Reflection)是 Java 被视为动态语言的关键,反射机制允许程序在 执行期 借助于 Reflection APl 取得任何 类的内部信息,并能直接操作 任意对象的内部属性及方法。
Class c = Class.forName("java.lang.String")
加载完类之后,在堆内存的方法区中就产生了一个 Class 类型的对象(一个类只有一个 Class 对象),这个对象 就包含了完整的类的结构信息。我们可以通过这个对象看到类的结构。这个对象就像一面镜子,透过这个镜子看到类的结构,所以,我们形象的称之为:反射。
- 正常方式:引入需要的 “包类” 名称 ➡ 通过
new实例化 ➡ 取得实例化对象 - 反射方式:实例化对象 ➡
getClass()方法 ➡ 得到完整的 “包类” 名称
1.3 Java 反射机制提供的功能
- 在运行时 判断任意一个对象所属的类
- 在运行时 构造任意一个类的对象
- 在运行时 判断任意一个类所具有的成员变量和方法
- 在运行时 获取泛型信息
- 在运行时 调用任意一个对象的成员变量和方法
- 在运行时处理 注解
- 生成 动态代理
1.4 反射的优点和缺陷
- 优点:可以实现动态创建对象和编译,体现出很大的灵活性。
- 缺点:对性能有影响。使用反射基本上是一种解释操作,我们可以告诉 JVM,我们希望做什么并且它满足我们的要求。这类操作总是慢于直接执行相同的操作。
1.5 反射相关的主要 API
java.lang.Class:代表一个类java.lang.reflect.Method:代表类的方法java.lang.reflect.Field:代表类的成员变量java.lang.reflect.Constructor:代表类的构造器
1.6 代码示例
package com.pp.reflection;// 示例说明:什么叫反射
public class Test01 {public static void main(String[] args) throws ClassNotFoundException {// 通过反射获取 Class 对象Class c1 = Class.forName("com.pp.reflection.User");System.out.println(c1);Class c2 = Class.forName("com.pp.reflection.User");Class c3 = Class.forName("com.pp.reflection.User");// 一个类在内存中只有一个 Class 对象// 一个类被加载后,类的整个结构都会被封装在 Class 对象中System.out.println(c1.hashCode());System.out.println(c2.hashCode());System.out.println(c3.hashCode());}
}// 实体类
class User {private String name;private int id;private int age;public User() {}public User(String name, int id, int age) {this.name = name;this.id = id;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getId() {return id;}public void setId(int id) {this.id = id;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "User{" +"name='" + name + '\'' +", id=" + id +", age=" + age +'}';}
}

2.Class 类
2.1 什么是 Class 类
在 Object 类中定义了以下的方法,此方法将被所有子类继承。
public final Class getClass()
以上的方法返回值的类型是一个 Class 类,此类是 Java 反射的源头,实际上所谓反射,从程序的运行结果来看也很好理解,即:可以通过对象反射求出类的名称。

对象照镜子后可以得到的信息:某个类的 属性、方法 和 构造器、某个类到底实现了哪些 接口。
对于每个类而言,JRE 都为其保留一个不变的 Class 类型的对象。一个 Class 对象包含了特定某个结构(class / interface / enum / annotation / primitive type / void / [])的有关信息。
- Class 本身也是一个类。
- Class 对象只能由系统建立对象。
- 一个加载的类在 JVM 中只会有一个 Class 实例。
- 一个 Class 对象对应的是一个加载到 JVM 中的一个
.class文件。 - 每个类的实例都会记得自己是由哪个 Class 实例所生成。
- 通过 Class 可以完整地得到一个类中的所有被加载的结构。
- Class 类是 Reflection 的根源,针对任何你想动态加载、运行的类,唯有先获得相应的 Class 对象。
2.2 Class 类的常用方法
| | |
|---|---|
static ClassforName(String name) | 返回指定类名 name 的 Class 对象 |
Object newInstance() | 调用缺省构造函数,返回 Class 对象的一个实例 |
getName() | 返回此 Class 对象所表示的实体(类,接口,数组类或 void)的名称。 |
Class getSuperClass() | 返回当前 Class 对象的父类的 Class 对象 |
Class[] getinterfaces() | 获取当前 Class 对象的接口 |
ClassLoader getClassLoader() | 返回该类的类加载器 |
Constructor[] getConstructors() | 返回一个包含某些 Constructor 对象的数组 |
Method getMethod(String name,Class.. T) | 返回一个 Method 对象,此对象的形参类型为 paramType |
Field[] getDeclaredFields() | 返回 Field 对象的一个数组 |
2.3 获取 Class 类
- 若已知 具体的类,通过类的
class属性获取,该方法最为安全可靠,程序性能最高。
Class clazz = Person.class;
- 已知 某个类的实例,调用该实例的
getClass()方法获取 Class 对象。
Class clazz = person.getClass();
- 已知 一个类的全类名,且该类在类路径下,可通过 Class 类的静态方法
forName()获取,可能抛出 ClassNotFoundException。
Class clazz = Class.forName("demo01.Student");
-
内置基本数据类型可以直接用类名
.Type。 -
还可以利用 ClassLoader。
package com.pp.reflection;// 测试 Class 类的创建方式有哪些
public class Test02 {public static void main(String[] args) throws ClassNotFoundException {Person person = new Student();System.out.println("这个人是:" + person.name);// 方式一:通过对象获得Class c1 = person.getClass();System.out.println(c1.hashCode());// 方式二:通过对象获得Class c2 = Class.forName("com.pp.reflection.Student");System.out.println(c2.hashCode());// 方式三:通过类名.classClass c3 = Student.class;System.out.println(c3.hashCode());// 方式四:基本数据类型的包装类都有一个 Type 属性Class c4 = Integer.TYPE;System.out.println(c4);// 方式五:获得父类类型Class c5 = c1.getSuperclass();System.out.println(c5);}
}class Person {public String name;public Person() {}public Person(String name) {this.name = name;}@Overridepublic String toString() {return "person{" +"name='" + name + '\'' +'}';}
}class Student extends Person {public Student() {this.name = "学生";}
}class Teacher extends Person {public Teacher() {this.name = "老师";}
}

3.4 哪些类型可以有 Class 对象
class:外部类,成员(成员内部类,静态内部类),局部内部类,匿名内部类。interface:接口[]:数组enum:枚举annotation:注解 @interfaceprimitive type:基本数据类型void
package com.pp.reflection;import java.lang.annotation.ElementType;public class Test03 {public static void main(String[] args) {Class c1 = Object.class; // 类Class c2 = Comparable.class; // 接口Class c3 = String[].class; // 一维数组Class c4 = int[][].class; // 二维数组Class c5 = Override.class; // 注解Class c6 = ElementType.class; // 枚举Class c7 = Integer.class; // 基本数据类型Class c8 = void.class; // voidClass c9 = Class.class; // ClassSystem.out.println(c1);System.out.println(c2);System.out.println(c3);System.out.println(c4);System.out.println(c5);System.out.println(c6);System.out.println(c7);System.out.println(c8);System.out.println(c9);// 只要元素类型与维度一样,就是同一个 Classint[] a = new int[10];int[] b = new int[100];System.out.println(a.getClass().hashCode());System.out.println(b.getClass().hashCode());}
}

🚀 本篇博文为《【狂神说Java】注解和反射》的学习笔记。
相关文章:
【Java】Java 的反射机制(一):反射概述
Java 的反射机制(一):反射概述 1.反射概述1.1 静态语言 / 动态语言1.1.1 动态语言1.1.2 静态语言 1.2 Java Reflection1.3 Java 反射机制提供的功能1.4 反射的优点和缺陷1.5 反射相关的主要 API1.6 代码示例 2.Class 类2.1 什么是 Class 类2.…...
Monorepo pnpm 模式管理多个 web 项目
Monorepo pnpm 模式管理多个 web 项目 Monorepo pnpm 模式管理多个 web 项目项目地址git flow 工作流程pnpm workspace.npmrc初始化项目架构引入Husky规范git提交配置eslint和prettiereslint 配置prettier 配置 配置lint-staged创建项目创建shared项目全局安装 vue在 packages …...
2024年诺贝尔物理学奖颁发给了机器学习与神经网络领域的研究者,看是有点意料之外,其实也在情理之中。
近日,2024年诺贝尔物理学奖颁发给了机器学习与神经网络领域的研究者,这是历史上首次出现这样的情况。这项奖项原本只授予对自然现象和物质的物理学研究作出重大贡献的科学家,如今却将全球范围内对机器学习和神经网络的研究和开发作为了一种能…...
《深入理解 C++策略模式的变体:编程灵活性的新维度》
在 C编程的广阔领域中,设计模式起着至关重要的作用,它们为软件架构提供了可复用的解决方案。其中,策略模式是一种非常强大的设计模式,它允许算法的行为在运行时根据不同的策略进行改变。而策略模式的变体则进一步扩展了其灵活性和…...
一起体验AI动手实验,OceanBase 2024 年度发布会精彩预告
2024年OceanBase年度发布会将于10月23日在北京望京凯悦酒店举行。此次大会围绕“不止于记录”的主题,共同探讨当前数据库领域的前沿话题,包含主论坛、分论坛、AI 动手实训营、开源技术交流会等多个环节,诚邀全国各地的企业和开发者共同参与&a…...
Download Vmware Fusion (free for person)
1. web link ProductFiles - Support Portal - Broadcom support portal 2. Register user (Required) use your email to register a account 3. login and download note: the username is the email name....
【Java数据结构】二叉树
【本节目标】 1. 掌握树的基本概念 2. 掌握二叉树概念及特性 3. 掌握二叉树的基本操作 4. 完成二叉树相关的面试题练习 一. 树型结构 1 概念★ 树是一种 非线性 的数据结构,它是由 n ( n>0 )个有限结点组成一个具有层次关系的集…...
虎牙Android面试题及参考答案
给个数组,找出数组中第 k 大的数(利用快排思想 / 用小顶堆,他说可以用大顶堆?) 利用快排思想:快速排序的核心思想是分治和分区。在找数组中第 k 大的数时,每次选择一个基准元素,将数组分为两部分,左边部分小于基准元素,右边部分大于基准元素。如果基准元素最终的下标…...
C++:错误代码分析<2>
🌏主页:R6bandito_ 🚀所属专栏:C/C错误代码收集整理 源码 考虑以下代码: void do_some_work() {std::cout << "Do some work" << std::endl; }int main(int argc, const char* argv[]) {std::…...
怎么ping网络ip地址通不通
怎么Ping网络IP地址通不通?要检查网络中的IP地址是否连通,可以使用Ping命令。Ping命令通过发送ICMP(Internet Control Message Protocol,因特网控制消息协议)Echo请求报文并等待回应,来判断目标主机是否可…...
前端新机部署
编辑器:vscode 下载地址 vscode常用插件 显示代码修改历史、作者等信息 GitLens Nodejs版本 Node版本管理工具 Nvm下载地址 nvm常用命令: nvm ls // 查看安装的所有node.js的版本nvm list available //查看可以安装的所有node.js版本nvm install 版本…...
对比 Babel、SWC 和 Oxc:JavaScript 和 TypeScript 工具的未来
随着现代前端开发的快速演变,JavaScript 和 TypeScript 的工具链不断更新,以满足开发者对性能和效率的需求。我们将对比三款流行的工具:Babel、SWC 和 Oxc,重点分析它们的特点、性能、应用场景以及适用性。 1. Babel:…...
MySQL SELECT 查询(三):查询常用函数大全
MySQL SELECT 查询(三):查询常用函数大全 1. 单行函数 单行函数是 SQL 中一类重要的函数,它们可以对单行数据进行处理,并返回单个结果。单行函数可以嵌套使用,并提供灵活的数据处理能力。 1.1 定义 只对单…...
axios 的 get 请求传参数
在使用 Axios 发起 GET 请求时,参数通常是通过 URL 的查询字符串来传递的。Axios 提供了一个简洁的接口来构建这样的请求,并自动将参数附加到 URL 上。 以下是一个使用 Axios 发起 GET 请求并传递参数的示例: const axios require(axios);…...
用C++编写信息管理系统(歌单信息管理)
C语言是面向过程的编程语言,而C是面向对象的编程语言,在书写代码时风格有所不同(也存在很多共性)。 程序说明 本次系统程序使用的是C语言进行编写,主要考虑怎么实现面向对象的问题。 因为本次程序属于小型系统程序&…...
对层级聚类树进行模块分割,定位基因在哪个模块中
拷贝数据到 ImageGP (http://www.ehbio.com/Cloud_Platform/front/#/analysis?pageb%27Ng%3D%3D%27),并设置参数. ID untrt_N61311 untrt_N052611 untrt_N080611 untrt_N061011 trt_N61311 trt_N052611 trt_N080611 trt_N061011 ENSG000…...
机器学习【金融风险与风口评估及其应用】
机器学习【金融风险与风口评估及其应用】 一、机器学习在金融风险评估中的应用1.提升评估准确性2.实现自动化和智能化3.增强风险管理能力4.信用评估5.风险模型6.交易策略7.欺诈检测 二、机器学习在金融风口评估中的应用1.识别市场趋势2.评估创新潜力3.优化投资策略4. 自然语言处…...
【计算机网络 - 基础问题】每日 3 题(三十八)
✍个人博客:https://blog.csdn.net/Newin2020?typeblog 📣专栏地址:http://t.csdnimg.cn/fYaBd 📚专栏简介:在这个专栏中,我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话,欢迎点赞…...
深入浅出MongoDB(五)
深入浅出MongoDB(五) 文章目录 深入浅出MongoDB(五)可重试读取可重试写入读关注readConcern支持写关注 可重试读取 可重试读取允许mongodb驱动程序在遇到某些网络或服务器错误时,自动重试某些读取操作一次。只有连接到…...
【conda】创建、激活、删除虚拟环境
前言一、创建虚拟环境二、删除虚拟环境总结 前言 主要是记录一下步骤 一、创建虚拟环境 地址栏输入cmd,唤起命令符栏目,就可以在指定目录下创建虚拟环境了。 这样方便日后在pycharm直接配置虚拟环境。 conda create -n yolo5-lite python3.9 -y简单来说…...
以下是对华为 HarmonyOS NETX 5属性动画(ArkTS)文档的结构化整理,通过层级标题、表格和代码块提升可读性:
一、属性动画概述NETX 作用:实现组件通用属性的渐变过渡效果,提升用户体验。支持属性:width、height、backgroundColor、opacity、scale、rotate、translate等。注意事项: 布局类属性(如宽高)变化时&#…...
Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...
用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...
Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...
Reasoning over Uncertain Text by Generative Large Language Models
https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...
HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...
【网络安全】开源系统getshell漏洞挖掘
审计过程: 在入口文件admin/index.php中: 用户可以通过m,c,a等参数控制加载的文件和方法,在app/system/entrance.php中存在重点代码: 当M_TYPE system并且M_MODULE include时,会设置常量PATH_OWN_FILE为PATH_APP.M_T…...
Git常用命令完全指南:从入门到精通
Git常用命令完全指南:从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...
解析奥地利 XARION激光超声检测系统:无膜光学麦克风 + 无耦合剂的技术协同优势及多元应用
在工业制造领域,无损检测(NDT)的精度与效率直接影响产品质量与生产安全。奥地利 XARION开发的激光超声精密检测系统,以非接触式光学麦克风技术为核心,打破传统检测瓶颈,为半导体、航空航天、汽车制造等行业提供了高灵敏…...
Visual Studio Code 扩展
Visual Studio Code 扩展 change-case 大小写转换EmmyLua for VSCode 调试插件Bookmarks 书签 change-case 大小写转换 https://marketplace.visualstudio.com/items?itemNamewmaurer.change-case 选中单词后,命令 changeCase.commands 可预览转换效果 EmmyLua…...
