【注解和反射】获取类运行时结构

news2024/12/24 0:05:01

继上一篇博客【注解和反射】类加载器-CSDN博客

目录

七、获取类运行时结构

测试

getFields()和getDeclaredFields()

getMethods()和getDeclaredMethods()


七、获取类运行时结构

获取类运行时结构通常指的是在Java等面向对象编程语言中,使用反射(Reflection)机制来检查类、接口、字段(Field)和方法(Method)等程序元素的能力。这种能力允许你在运行时动态地获取类的信息,并且可以调用类的方法、改变字段的值等。

在Java中,获取类运行时结构主要包括以下几个方面:

  1. 获取Class对象: 要获取类的运行时结构,首先需要获取代表该类的Class对象。这可以通过多种方式实现,例如使用.class语法、Class.forName()方法或通过对象的getClass()方法。

  2. 获取类的名称: 通过Class对象的getName()方法可以获取类的全限定名(包括包名)。

  3. 获取类的修饰符: 使用getModifiers()方法可以获取类的修饰符(如publicabstractfinal等),通常与Modifier.toString()方法结合使用以获取可读的修饰符字符串。

  4. 获取类的父类和实现的接口: 通过getSuperclass()方法可以获取类的直接父类,而getInterfaces()方法则返回当前类实现的接口数组。

  5. 获取类的字段: 使用getDeclaredFields()方法可以获取类中声明的所有字段,无论访问权限如何。而getFields()方法仅返回public字段。

  6. 获取类的方法: 类似地,getDeclaredMethods()方法返回类中声明的所有方法,而getMethods()方法仅返回public方法,包括继承自父类的方法。

  7. 获取类的构造器: 通过getDeclaredConstructors()方法可以获取类的所有构造器,而getConstructors()方法仅返回public构造器。

  8. 获取类的注解: 如果类、方法、字段等上面有注解(Annotation),可以使用getAnnotations()getDeclaredAnnotation()等方法来获取这些注解信息。

  9. 获取类的内部类和接口: 通过getDeclaredClasses()方法可以获取当前类中声明的所有内部类和接口。

  10. 判断类的特性Class类提供了一系列的方法来判断类的特性,如isInterface()isEnum()isAnnotation()isAnonymousClass()isArray()isPrimitive()等。

获取类运行时结构的能力在Java中非常强大,它允许开发者在程序运行时动态地分析和操作类,这在很多场景下都很有用,比如框架设计、单元测试、序列化和反序列化、依赖注入等。然而,使用反射也需要谨慎,因为它可能会破坏封装性,降低性能,并且使代码更加复杂和难以维护。

测试

首先,我们需要定义一个 User 类,

class User{
  private String name;
  private int id;
  private int age;

  public User(String name, int id, int age) {
    this.name = name;
    this.id = id;
    this.age = age;
  }

  public User() {
  }

  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;
  }

  @Override
  public String toString() {
    return "User{" +
      "name='" + name + '\'' +
      ", id=" + id +
      ", age=" + age +
      '}';
  }
}

在代码示例中,Test05 类有一个 main 方法,该方法执行了以下操作:

  1. 创建了一个 User 类的对象 user
  2. 通过调用 user.getClass() 获取了 User 类的 Class 对象,并将其存储在变量 c1 中。
  3. 打印了 c1 所代表的类的全名(包名 + 类名)和简单类名(仅类名)。
  4. 打印了一行分隔符 -------
  5. 获取了 c1 所代表的类声明的所有字段(不包括继承的字段),并遍历打印了每个字段的信息。

public class Test05 {
  public static void main(String[] args) throws ClassNotFoundException {
    User user = new User();
    Class c1 = user.getClass();
    System.out.println(c1.getName());
    System.out.println(c1.getSimpleName());

    System.out.println("-------");
    // Field[] fields = c1.getFields();
    Field[] fields = c1.getDeclaredFields();
    for(Field f: fields){
      System.out.println(f);
    }

  }
}

这里是输出结果的详细分析:

  1. System.out.println(c1.getName()); 打印了User类的完全限定名,即包括包名(如果有的话)和类名。因为User类没有指定包名,所以输出就是User

  2. System.out.println(c1.getSimpleName()); 打印了User类的简单名字,也就是不包括包名的类名,所以输出还是User

  3. 在打印了一行分隔符之后,代码通过c1.getDeclaredFields()获取了User类中声明的所有字段,包括privateprotected、默认(包私有)和public字段。在这个例子中,User类有三个private字段:nameidage。这些字段被打印出来,包括它们的访问修饰符、类型、类名和字段名。

getFields()和getDeclaredFields()

在Java的反射API中,getFields()getDeclaredFields()方法都用于获取类的字段,但它们在获取字段的范围和访问权限上有明显的区别:

  1. getFields():

    • 这个方法返回的是当前类及其所有父类(包括Object类)中声明的public字段
    • 它不包括当前类中声明的privateprotected和默认(包私有)访问级别的字段。
    • 如果当前类或其父类中没有public字段,那么这个方法将返回一个长度为0的数组。
  2. getDeclaredFields():

    • 这个方法返回的是当前类中声明的所有字段,无论它们的访问权限是什么(publicprivateprotected或默认)。
    • 它不包括父类中声明的任何字段,只查看当前类的字段。
    • 即使当前类中没有字段,这个方法也会返回一个数组,只不过数组的长度是0。

通常,如果你只对当前类的字段感兴趣,而不关心父类的字段,那么你应该使用getDeclaredFields()。同时,如果你需要访问非public字段,你也需要使用getDeclaredFields(),因为getFields()不会返回这些字段。

另外,值得注意的是,如果你使用getDeclaredFields()获取了非public字段,并且想要访问或修改这些字段的值,你需要先调用Field.setAccessible(true)来允许访问这些字段,否则会抛出IllegalAccessException异常。

getMethods()getDeclaredMethods()

现在,让我们来讨论getMethods()getDeclaredMethods()的区别:

  1. getMethods():

    • 这个方法返回当前类及其所有父类(包括Object类)中声明的所有public方法。
    • 它不包括当前类中声明的privateprotected和默认(包私有)访问级别的方法。
    • 返回的数组包含了从当前类开始,沿着继承链向上直到Object类的所有public方法。
  2. getDeclaredMethods():

    • 这个方法返回当前类中声明的所有方法,无论它们的访问权限是什么(publicprivateprotected或默认)。
    • 它不包括父类中声明的任何方法,只查看当前类的方法。
    • 即使当前类中没有方法,这个方法也会返回一个数组,只不过数组的长度是0。

与字段的情况类似,如果你只对当前类的方法感兴趣,而不关心父类的方法,那么你应该使用getDeclaredMethods()。同时,如果你需要访问非public方法,你也需要使用getDeclaredMethods(),因为getMethods()不会返回这些方法。

同样值得注意的是,如果你使用getDeclaredMethods()获取了非public方法,并且想要调用这些方法,你需要先调用Method.setAccessible(true)来允许访问这些方法,否则会抛出IllegalAccessException异常。

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

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

相关文章

【git学习】Git 的基本操作

文章目录 🚀创建 Git 本地仓库🚀配置 Git🚀认识⼯作区、暂存区、版本库🚀添加⽂件操作 🚀创建 Git 本地仓库 仓库是进⾏版本控制的⼀个⽂件⽬录。我们要想对⽂件进⾏版本控制,就必须先创建⼀个仓库出来。 …

谷歌发布基于声学建模的无限虚拟房间增强现实鲁棒语音识别技术

声学室模拟允许在AR眼镜上以最少的真实数据进行训练,用于开发鲁棒的语音识别声音分离模型。 随着增强现实(AR)技术的强大和广泛应用,它能应用到各种日常情境中。我们对AR技术的潜能感到兴奋,并持续不断地开发和测试新…

web前端框架设计第六课-样式绑定

web前端框架设计第六课-样式绑定 一.预习笔记 1.class属性绑定 给P标签绑定一个类样式,类名为active。当active取值为true时,表示绑定样式成功,取值为false时,取消绑定 以对象形式给P标签绑定多个类样式 以数组形式给P标签绑定多…

网络安全新挑战:通用人工智能(AGI)等级保护指南

通用人工智能(AGI)的发展现状及趋势 随着2023年大语言模型应用的划时代突破,以ChatGPT为杰出代表的此类技术犹如一股洪流,彻底颠覆了人类与机器智能交互的疆界,引领通用人工智能(AGI)步入一个崭…

网络基础(day3)建议在电脑端注册登陆观看!!!

【 理论重点】 网络是什么&#xff1f; &#xff08;网络是载体&#xff0c;目的是传输互联网中的数据&#xff0c;数据是终端产生<手机、电脑、服务器等>。&#xff09; 如何组件网络&#xff08;良性网络架构&#xff09;&#xff1f;有网络架构思维&#xff0c;得按层…

宜搜科技死磕港交所上市:从搜索引擎到广告投放,业绩疲态凸显

近日&#xff0c;宜搜科技控股有限公司&#xff08;下称“宜搜科技”&#xff09;向港交所递交招股书&#xff0c;计划在香港主板上市&#xff0c;中银国际为其独家保荐人。 值得注意的是&#xff0c;宜搜科技已在资本市场辗转多年。该公司曾于2014年向纽交所递交上市申请&…

easyExcel快速入门

目录 &#x1f9c2;1.简单介绍 &#x1f32d;2.快速入门 &#x1f953;1.导入依赖 &#x1f37f;2.导出到excel &#x1f38f;3.读入数据 &#x1f389;4.下载 1.简单介绍 传统操作Excel大多都是利用Apach POl进行操作的,但是POI框架并不完善,使用过程非常繁琐且有较多…

Github进行fork后如何与原仓库同步

前言 fork了一个仓库以后怎么同步源仓库的代码&#xff1f; 步骤 1、执行命令 git remote -v 查看你的远程仓库的路径。 以一个实际例子说明&#xff0c; 来源仓库&#xff1a; TheFirstLineOfCode/basaltgit remote -v得到&#xff1a; origin https://github.com/ghmi…

Redis之路系列(5)功夫在诗外

5 拓展篇—功夫在诗外 6.0新特性 相对都比较鸡肋&#xff0c;谨慎在生产环境使用 ACL安全策略 Redis6版本推出了ACL(Access Control List)访问控制权限 的功能&#xff0c;基于此功能&#xff0c;可以设置多个用户&#xff0c;并且给每个用户单独设 置命令权限和数据权限。 …

机器学习/算法工程师面试题目与答案-深度学习部分1

机器学习/算法工程师面试题目与答案-深度学习部分 BatchNormalization的作用梯度消失循环神经网络&#xff0c;为什么好?什么是GroupConvolution什么是RNN神经网络中权重共享的是&#xff1f;神经网络激活函数&#xff1f;为什么在深度学习中常进行finetuning画GRU结构图什么是…

python+django校园社交高校交友网站2x7r5.

本课题使用Python语言进行开发。代码层面的操作主要在PyCharm中进行&#xff0c;将系统所使用到的表以及数据存储到MySQL数据库中&#xff0c;方便对数据进行操作本课题基于WEB的开发平台&#xff0c;设计的基本思路是&#xff1a; 前端&#xff1a;vue.jselementui 框架&#…

探索Web3:去中心化的互联网新时代

引言 在过去的几十年里&#xff0c;互联网已经改变了我们的生活方式、商业模式以及社交互动方式。然而&#xff0c;一个新的技术浪潮——Web3正在崭露头角&#xff0c;预示着一个去中心化的互联网新时代的来临。本文将深入探讨Web3技术的定义、特点以及其对未来互联网发展的影…

跨平台SIP 客户端-linphone下载、使用、开启视频H264

linphone 介绍 Linphone 是一种开源的语音和视频通信应用程序&#xff0c;它提供了基于互联网协议&#xff08;IP&#xff09;的实时通信功能。用于语音/视频通话、即时消息和电话会议的开源 SIP 电话。它适用于移动和桌面环境&#xff08;iOS、Android、GNU/Linux、macOS、Win…

【ensp】网关冗余vrrp实验

基础文字知识复习时&#xff0c;添加&#xff0c;下文仅拓扑以及核心配置以及结果分析 冗余路由器 核心代码&#xff1a; int g0/0/0 [R1-GigabitEthernet0/0/0]vrrp vrid 1 virtual-ip 192.168.10.1 ###设置虚拟ip [R1-GigabitEthernet0/0/0]vrrp vrid 1 priority 120 …

Flutter-自定义画板

效果 功能 支持绘制线、圆、矩形&#xff0c;支持拓展支持撤回上一步支持清空画板支持自定义画笔颜色&#xff0c;宽度 实现 定义绘制类型 /// 类型 enum ShapeType {//线line,//圆circle,//矩形rectangle,//拓展 }定义绘制抽象类 import dart:ui;/// 绘制抽象类 abstract…

云原生Service Mesh服务网格简单介绍

serviceMesh是什么 Service Mesh是一个用于处理服务间通信的基础设施层&#xff0c;旨在实现云原生应用复杂服务拓扑中的可靠请求传递。其基本构成是一组与应用一起部署的轻量级网络代理&#xff0c;这些代理对应用来说是透明的。Service Mesh通过统一的方式来控制和处理服务间…

数据结构-二叉树-链式

一、链式二叉树的结构 typedef int BTNodeDataType; typedef struct BTNode {BTNodeDataType data;struct BTNode* left;struct BTNode* right; }BTNode; 二叉树的前中后序遍历 前序&#xff1a;根左右 中序&#xff1a;左根右 后序&#xff1a;左右根 void PreOrder(BTNo…

大语言模型Ollama

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl Ollama简介 Ollama是一个开源的大语言模型平台&#xff0c;它允许用户在本地环境中运行、创建和共享大型语言模型。Ollama提供了丰富的功能和特性&#xff0c;使得用户可以…

Jenkins - macOS 上安装

文章目录 关于 JenkinsmacOS 上安装 Jenkins方式一&#xff1a;brew方式二&#xff1a;tomcat Jenkins war 关于 Jenkins 官网上下载Jenkins并将其安装到持续集成服务器 https://jenkins.io/download/ macOS 上安装 Jenkins 现在本 macOS 上测试 https://www.jenkins.io/do…

更新至2022年上市公司数字化转型数据合集(四份数据合集)

更新至2022年上市公司数字化转型数据合集&#xff08;四份数据合集&#xff09; 一、2000-2022年上市公司数字化转型数据&#xff08;年报词频、文本统计&#xff09; 二、2007-2022年上市公司数字化转型数据&#xff08;年报和管理层讨论&#xff09;&#xff08;含原始数据…