当前位置: 首页 > news >正文

【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:注解 @interface
  • primitive 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>

&#x1f30f;主页&#xff1a;R6bandito_ &#x1f680;所属专栏&#xff1a;C/C错误代码收集整理 源码 考虑以下代码&#xff1a; void do_some_work() {std::cout << "Do some work" << std::endl; }int main(int argc, const char* argv[]) {std::…...

怎么ping网络ip地址通不通

怎么Ping网络IP地址通不通&#xff1f;要检查网络中的IP地址是否连通&#xff0c;可以使用‌Ping命令。Ping命令通过发送ICMP&#xff08;Internet Control Message Protocol&#xff0c;因特网控制消息协议&#xff09;Echo请求报文并等待回应&#xff0c;来判断目标主机是否可…...

前端新机部署

编辑器&#xff1a;vscode 下载地址 vscode常用插件 显示代码修改历史、作者等信息 GitLens Nodejs版本 Node版本管理工具 Nvm下载地址 nvm常用命令&#xff1a; nvm ls // 查看安装的所有node.js的版本nvm list available //查看可以安装的所有node.js版本nvm install 版本…...

对比 Babel、SWC 和 Oxc:JavaScript 和 TypeScript 工具的未来

随着现代前端开发的快速演变&#xff0c;JavaScript 和 TypeScript 的工具链不断更新&#xff0c;以满足开发者对性能和效率的需求。我们将对比三款流行的工具&#xff1a;Babel、SWC 和 Oxc&#xff0c;重点分析它们的特点、性能、应用场景以及适用性。 1. Babel&#xff1a;…...

MySQL SELECT 查询(三):查询常用函数大全

MySQL SELECT 查询&#xff08;三&#xff09;&#xff1a;查询常用函数大全 1. 单行函数 单行函数是 SQL 中一类重要的函数&#xff0c;它们可以对单行数据进行处理&#xff0c;并返回单个结果。单行函数可以嵌套使用&#xff0c;并提供灵活的数据处理能力。 1.1 定义 只对单…...

axios 的 get 请求传参数

在使用 Axios 发起 GET 请求时&#xff0c;参数通常是通过 URL 的查询字符串来传递的。Axios 提供了一个简洁的接口来构建这样的请求&#xff0c;并自动将参数附加到 URL 上。 以下是一个使用 Axios 发起 GET 请求并传递参数的示例&#xff1a; const axios require(axios);…...

用C++编写信息管理系统(歌单信息管理)

C语言是面向过程的编程语言&#xff0c;而C是面向对象的编程语言&#xff0c;在书写代码时风格有所不同&#xff08;也存在很多共性&#xff09;。 程序说明 本次系统程序使用的是C语言进行编写&#xff0c;主要考虑怎么实现面向对象的问题。 因为本次程序属于小型系统程序&…...

对层级聚类树进行模块分割,定位基因在哪个模块中

拷贝数据到 ImageGP (http://www.ehbio.com/Cloud_Platform/front/#/analysis?pageb%27Ng%3D%3D%27)&#xff0c;并设置参数. 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 题(三十八)

✍个人博客&#xff1a;https://blog.csdn.net/Newin2020?typeblog &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/fYaBd &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞…...

深入浅出MongoDB(五)

深入浅出MongoDB&#xff08;五&#xff09; 文章目录 深入浅出MongoDB&#xff08;五&#xff09;可重试读取可重试写入读关注readConcern支持写关注 可重试读取 可重试读取允许mongodb驱动程序在遇到某些网络或服务器错误时&#xff0c;自动重试某些读取操作一次。只有连接到…...

【conda】创建、激活、删除虚拟环境

前言一、创建虚拟环境二、删除虚拟环境总结 前言 主要是记录一下步骤 一、创建虚拟环境 地址栏输入cmd&#xff0c;唤起命令符栏目&#xff0c;就可以在指定目录下创建虚拟环境了。 这样方便日后在pycharm直接配置虚拟环境。 conda create -n yolo5-lite python3.9 -y简单来说…...

EtherNet/IP转DeviceNet协议网关详解

一&#xff0c;设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络&#xff0c;本网关连接到EtherNet/IP总线中做为从站使用&#xff0c;连接到DeviceNet总线中做为从站使用。 在自动…...

CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云

目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元&#xff08;GRU&#xff09;长短期记忆神经网络&#xff08;LSTM&#xff09…...

在WSL2的Ubuntu镜像中安装Docker

Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包&#xff1a; for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...

STM32HAL库USART源代码解析及应用

STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...

PydanticAI快速入门示例

参考链接&#xff1a;https://ai.pydantic.dev/#why-use-pydanticai 示例代码 from pydantic_ai import Agent from pydantic_ai.models.openai import OpenAIModel from pydantic_ai.providers.openai import OpenAIProvider# 配置使用阿里云通义千问模型 model OpenAIMode…...

VSCode 使用CMake 构建 Qt 5 窗口程序

首先,目录结构如下图: 运行效果: cmake -B build cmake --build build 运行: windeployqt.exe F:\testQt5\build\Debug\app.exe main.cpp #include "mainwindow.h"#include <QAppli...

Win系统权限提升篇UAC绕过DLL劫持未引号路径可控服务全检项目

应用场景&#xff1a; 1、常规某个机器被钓鱼后门攻击后&#xff0c;我们需要做更高权限操作或权限维持等。 2、内网域中某个机器被钓鱼后门攻击后&#xff0c;我们需要对后续内网域做安全测试。 #Win10&11-BypassUAC自动提权-MSF&UACME 为了远程执行目标的exe或者b…...

【2D与3D SLAM中的扫描匹配算法全面解析】

引言 扫描匹配(Scan Matching)是同步定位与地图构建(SLAM)系统中的核心组件&#xff0c;它通过对齐连续的传感器观测数据来估计机器人的运动。本文将深入探讨2D和3D SLAM中的各种扫描匹配算法&#xff0c;包括数学原理、实现细节以及实际应用中的性能对比&#xff0c;特别关注…...

【笔记】结合 Conda任意创建和配置不同 Python 版本的双轨隔离的 Poetry 虚拟环境

如何结合 Conda 任意创建和配置不同 Python 版本的双轨隔离的Poetry 虚拟环境&#xff1f; 在 Python 开发中&#xff0c;为不同项目配置独立且适配的虚拟环境至关重要。结合 Conda 和 Poetry 工具&#xff0c;能高效创建不同 Python 版本的 Poetry 虚拟环境&#xff0c;接下来…...