Java反射详解(二)

news2025/1/5 9:21:57

上一篇博客:Java反射详解(一)

 写在前面:大家好!我是晴空๓。如果博客中有不足或者的错误的地方欢迎在评论区或者私信我指正,感谢大家的不吝赐教。我的唯一博客更新地址是:https://ac-fun.blog.csdn.net/。非常感谢大家的支持。一起加油,冲鸭!
用知识改变命运,用知识成就未来!加油 (ง •̀o•́)ง (ง •̀o•́)ง

文章目录

  • 前言
  • 获取名称信息
    • getName()
    • getSimpleName()
    • getCanonicalName()
    • getPackage()
    • 总览
  • 获取字段信息
    • 示例类
    • getFields()
    • getDeclaredFields()
    • getField(String name)
    • getDeclaredField(String name)
    • Field类
  • 获取方法信息
    • Method类
  • 总结

前言

 在上一篇博客主要说明了反射的基本概念以及 Class类 与反射的关系,以及如何获取 Class对象。获取 Class对象 之后我们就可以获取类的信息以及基于这些信息进行一些操作,也就是我们所说的 反射。下面来逐一介绍一下我们可以通过 Class对象 执行哪些操作。

获取名称信息

Class对象 提供了多种方法来获取与类名称有关的信息,具体方法如下:

getName()

 返回类的真实名称,包括包名。这种名称在编译期间形成,在 Java 虚拟机内部使用(主要用于JVM 在运行时进行类型检查和加载类时使用),通常与编译器生成的符号名称相对应。例如,对于 java.lang.String 类,getName() 将返回 “java.lang.String”

public class TestClass {
    @Test
    public void test() {
        Class<String> stringClass = String.class;
        String className = stringClass.getName();
        System.out.println(className); // java.lang.String
    }
}

 这里需要注意该方法对于数组内部类有特殊表示。当用于数组时它使用 [ 表示数组,有几个 [ 就表示是几维数组;数组的类型用一个字符表示,I 表示 intL 表示类或者接口。

public class TestClass {

    @Test
    public void test() {
        int[][] arr = new int[10][10];
        String className = arr.getClass().getName();
        System.out.println(className); // [[I
    }
}

 对于引用类型的数组末尾会带一个分号(例如String[].class会显示 [Ljava.lang.String;)。其他类型与字符的对应关系为:

类型对应字符
booleanZ
byteB
charC
doubleD
floatF
longJ
shortS

getSimpleName()

 返回类的实际名称,不带包信息。例如,对于java.lang.String 类,getSimpleName() 将返回 “String”

public class TestClass {
    @Test
    public void test() {
        Class<String> stringClass = String.class;
        String className = stringClass.getSimpleName();
        System.out.println(className); // String
    }
}

getCanonicalName()

 该方法返回的名称更为友好,它通常会去掉内部命名空间中的冗余部分并且更加易读。例如同样对于二维数组 int[][],该方法返回的是 int[][]getName() 则返回 [[I。这个方法返回的名称通常用于文档和公共 API 中,因为更具有可读性。

public class TestClass {
    @Test
    public void test() {
        int[][] arr = new int[10][10];
        String className = arr.getClass().getCanonicalName();
        System.out.println(className); // int[][]
    }
}

getPackage()

 返回包信息。

public class TestClass {
    @Test
    public void test() {
        Class<String> stringClass = String.class;
        Package aPackage = stringClass.getPackage();
        System.out.println(aPackage); // package java.lang, Java Platform API Specification, version 1.8
    }
}

总览

 不同 Class对象 的各种名称方法的返回值如下图所示:
不同Class对象的各种方法的返回值

获取字段信息

示例类

 为了方便演示这里手动写一个父类 Creature类 以及子类 Person类 具体代码如下:

Creature类:

package ReflectionTest;

import java.io.Serializable;

public class Creature implements Serializable {
    private char gender;
    public double weight;

    private void breath() {
        System.out.println("生物呼吸");
    }

    public void eat() {
        System.out.println("生物进食");
    }
}

Person类

package ReflectionTest;

public class Person extends Creature {
    private String name;
    protected String id;
    public String age;

    @Override
    public void eat() {
        super.eat();
    }

    public void run() {
        System.out.println("跑步");
    }

    protected void say() {
        System.out.println("说话");
    }
}

getFields()

 返回所有的 public 字段,包括其父类的,如果没有字段则返回空数组。返回类型为 Field[]Field类 也是 Java 反射 API 的一部分,也位于 java.lang.reflect 包下。通过 Field 类,程序可以在运行时访问和修改类的字段,即使这些字段是私有的。

package ReflectionTest;

import org.junit.Test;

import java.lang.reflect.Field;

public class TestClass {
    @Test
    public void test() {
        Class<Person> personClass = Person.class;
        Field[] fields = personClass.getFields();
        for (Field f : fields) {
            System.out.println(f);
            /**
             * 输出结果:
             * public java.lang.String ReflectionTest.Person.age
             * public double ReflectionTest.Creature.weight
             */
        }
    }
}

getDeclaredFields()

 返回本类声明的所有字段,包括非 public 字段,但是不包括父类的。

public class TestClass {
    @Test
    public void test() {
        Class<Person> personClass = Person.class;
        Field[] fields = personClass.getDeclaredFields();
        for (Field f : fields) {
            System.out.println(f);
            /**
             * 输出结果:
             * private java.lang.String ReflectionTest.Person.name
             * protected java.lang.String ReflectionTest.Person.id
             * public java.lang.String ReflectionTest.Person.age
             */
        }
    }
}

getField(String name)

 返回本类或者父类中指定名称的 public 字段,找不到则抛出异常 NoSuchFieldException

public class TestClass {
    @Test
    public void test() throws NoSuchFieldException {
        Class<Person> personClass = Person.class;
        Field field = personClass.getField("age");
        System.out.println(field); // public java.lang.String ReflectionTest.Person.age
    }
}

getDeclaredField(String name)

 返回本类中指定名称的 public 字段,找不到则抛出异常 NoSuchFieldException

Field类

Field 也有很多方法,可以获取字段的信息,也可以通过 Field 访问和操作指定对象中该字段的值。该类的基本方法有:

​​​​​​​​​​// 获取字段的名称
​​​​​​​​public String getName()
​​​​​​​​// 判断当前程序是否有该字段的访问权限
​​​​​​​​public boolean isAccessible()
​​​​​​​​// flag 设为 true 表示忽略 Java 的访问检查机制,以允许读写非 public 的字段
​​​​​​​​public void setAccessible(boolean flag)
​​​​​​​​// 获取指定对象 obj 中该字段的值
​​​​​​​​public Object get(Object obj)
​​​​​​​​// 将指定对象 obj 中该字段的值设为 value
​​​​​​​​public void set(Object obj, Object value)
// 返回字段的修饰符
​​​​​​​​public int getModifiers()
​​​​​​​​// 返回字段的类型
​​​​​​​​public Class<? > getType()
​​​​​​​​// 以基本类型操作字段
​​​​​​​​public void setBoolean(Object obj, boolean z)
​​​​​​​​public boolean getBoolean(Object obj)
​​​​​​​​public void setDouble(Object obj, double d)
​​​​​​​​public double getDouble(Object obj)
​​​​​​​​// 查询字段的注解信息
​​​​​​​​public <T extends Annotation> T getAnnotation(Class<T> annotationClass)
​​​​​​​​public Annotation[] getDeclaredAnnotations()
​​

getModifiers() 方法需要注意一下,该方法用于返回字段的修饰符,但是返回的是一个 int,我们可以通过 Modifier 类的静态方法 isPublic()、isStatic()、isPrivate()等方法 进行解读。

public class TestClass {
    @Test
    public void test() throws NoSuchFieldException {
        Class<Person> personClass = Person.class;
        Field field = personClass.getField("age");

        int modifier = field.getModifiers();
        System.out.println(modifier); // 1
        System.out.println("isPublic: " + Modifier.isPublic(modifier)); // isPublic: true
        System.out.println("isStatic: " + Modifier.isStatic(modifier)); // isStatic: false
        System.out.println("isPrivate: " + Modifier.isPrivate(modifier)); // isPrivate: false
    }
}

通过查看源码发现每一种修饰符 getModifiers() 方法都会返回特定的 int值,以下是代码中定义的修饰符常量及其含义:

  • PUBLIC:0x00000001,表示 public 修饰符。
  • PRIVATE:0x00000002,表示 private 修饰符。
  • PROTECTED:0x00000004,表示 protected 修饰符。
  • STATIC:0x00000008,表示 static 修饰符。
  • FINAL:0x00000010,表示 final 修饰符。
  • SYNCHRONIZED:0x00000020,表示 synchronized 修饰符。
  • VOLATILE:0x00000040,表示 volatile 修饰符。
  • TRANSIENT:0x00000080,表示 transient 修饰符。
  • NATIVE:0x00000100,表示 native 修饰符。
  • INTERFACE:0x00000200,表示 interface 修饰符。
  • ABSTRACT:0x00000400,表示 abstract 修饰符。
  • STRICT:0x00000800,表示 strictfp 修饰符。

Modifier 类提供了如下方法来检查修饰符:

  • isPublic(int mod):检查是否设置了 public 修饰符。
  • isPrivate(int mod):检查是否设置了 private 修饰符。
  • isProtected(int mod):检查是否设置了 protected 修饰符。
  • isStatic(int mod):检查是否设置了 static 修饰符。
  • isFinal(int mod):检查是否设置了 final 修饰符。
  • isSynchronized(int mod):检查是否设置了 synchronized 修饰符。
  • isVolatile(int mod):检查是否设置了 volatile 修饰符。
  • isTransient(int mod):检查是否设置了 transient 修饰符。
  • isNative(int mod):检查是否设置了 native 修饰符。
  • isInterface(int mod):检查是否设置了 interface 修饰符。
  • isAbstract(int mod):检查是否设置了 abstract 修饰符。
  • isStrict(int mod):检查是否设置了 strictfp 修饰符。

获取方法信息

 通过 Class对象 也可以获取类中的方法信息,方法使用方法与获取字段信息部分大体一致,这里就不在赘述代码示例了。具体方法如下:

返回所有的 public 方法,包括其父类的,如果没有方法,返回空数组
​​​​​​​​public Method[] getMethods()
返回本类声明的所有方法,包括 非public 的,但不包括父类的
​​​​​​​​public Method[] getDeclaredMethods()
返回本类或父类中指定名称和参数类型的public方法,找不到抛出异常 NoSuchMethodException
​​​​​​​​public Method getMethod(String name, Class<? >... parameterTypes)
返回本类中声明的指定名称和参数类型的方法,找不到抛出异常 NoSuchMethodException
​​​​​​​​public Method getDeclaredMethod(String name, Class<? >... parameterTypes)​​

Method类

 通过 Method类 可以获取方法的信息,也可以通过该类调用对象的方法,方法如下:

返回此 Method 表示的方法的名称。
public String getName()
返回此 Method 表示的方法的修饰符。与 Field类 的用法一致也是使用 Modifierpublic int getModifiers()
控制是否绕过 Java 语言的访问检查
public void setAccessible(boolean flag)
在指定对象obj上调用 Method 代表的方法,传递的参数列表为 args
public Object invoke(Object obj, Object... args)
返回此 Method 表示的方法的返回类型。
public Class<?> getReturnType()
返回此 Method 表示的方法的参数类型。
public Class<?>[] getParameterTypes()

Method类 还有很多方法,可以获取类的修饰符、参数、返回值、注解等信息,这里就不详细列举了。

总结

 本篇主要介绍了利用反射获取类的名称、获取类中的字段信息以及方法信息。后续再继续介绍如何通过反射创建对象和调用构造方法、获取 Class类 的类型信息、声明信息以及利用反射的一些具体应用。


未完待续……


  1. 《Java编程的逻辑》

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

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

相关文章

zentao ubuntu上安装

#下载ZenTaoPMS-21.2-zbox_amd64.tar.gz&#xff08;https://www.zentao.net/downloads.html&#xff09; https://dl.zentao.net/zentao/21.2/ZenTaoPMS-21.2-zbox_amd64.tar.gzcd /opt tar -zxvf ZenTaoPMS-21.2-zbox_amd64.tar.gz#启动 /opt/zbox/zbox start /opt/zbox/zbox…

逆境清醒文章总目录表

逆境清醒文章总目录表 零、时光宝盒&#x1f33b; &#xff08;https://blog.csdn.net/weixin_69553582 逆境清醒&#xff09; 《你的答案》歌曲原唱&#xff1a;阿冗&#xff0c;填 词&#xff1a;林晨阳、刘涛&#xff0c;谱曲&#xff1a;刘涛 也许世界就这样&#xff0c…

【嵌入式硬件】嵌入式显示屏接口

数字显示串行接口&#xff08;Digital Display Serial Interface&#xff09; SPI 不过多赘述。 I2C-bus interface 不过多赘述 MIPI DSI MIPI (Mobile Industry Processor Interface) Alliance, DSI (Display Serial Interface) 一般用于移动设备&#xff0c;下面是接口…

AI证件照制作 API 快速生成示例

AI证件照制作 API 快速生成证件照示例 本文将介绍一种 AI证件照制作 API 对接说明&#xff0c;它是可以通过输入人像照片URL以及自己喜欢的模板来制作各种风格的证件照。 接下来介绍下 AI证件照制作 API 的对接说明。 申请流程 要使用 API&#xff0c;需要先到 AI证件照制作…

一个在ios当中采用ObjectC和opencv来显示图片的实例

前言 在ios中采用ObjectC编程利用opencv来显示一张图片&#xff0c;并简单绘图。听上去似乎不难&#xff0c;但是实际操作下来&#xff0c;却不是非常的容易的。本文较为详细的描述了这个过程&#xff0c;供后续参考。 一、创建ios工程 1.1、选择ios工程类型 1.2、选择接口模…

006-Jetpack Compose for Android之传感器数据

需求分析 想要看看手机的传感器数据&#xff0c;看看滤波一下能玩点什么无聊的。先搞个最简单的&#xff0c;手机本身的姿态。 需求&#xff1a;采集手机姿态数据&#xff0c;显示在界面上。 那么我们需要&#xff1a; 一个文本标签类似的控件&#xff0c;显示手机姿态数据…

SpringBoot3 快速启动框架

文章目录 1 SpringBoot3 介绍 1.1 SpringBoot3 简介1.2 快速入门1.3 入门总结 2 SpringBoot3 配置文件 2.1 统一配置管理概述2.2 属性配置文件使用2.3 YAML配置文件使用2.4 批量配置文件注入2.5 多环境配置和使用 3 SpringBoot 整合 springMVC 3.1 实现过程3.2 web相关配置3.3…

大型ERP系统GL(总账管理)模块需求分析

主要介绍了GL系统的需求分析&#xff0c;包括系统概述、功能描述、帐薄管理、报表管理、期末处理、财务报表以及凭证的快速输入方式、可用性设计、保存、自动审核和打印等方面的内容。系统概述部分介绍了系统的功能结构和模块流程图。 功能描述部分详细描述了系统的基础资料和业…

利用python将图片转换为pdf格式的多种方法,实现批量转换,内置模板代码,全网最全,超详细!!!

文章目录 前言1、img2pdf库的使用1.2 安装img2pdf库1.3 案例演示&#xff08;模板代码&#xff09; 2、Pillow库的使用2.1 pillow库的安装2.2 案例演示&#xff08;模板代码&#xff09; 3、PyMuPDF库的使用3.1 安装pymupdf库3.2 案例演示&#xff08;模板代码&#xff09;2.3 …

协议幻变者:DeviceNet转ModbusTCP网关开启机器手臂智能新纪元

技术背景DeviceNet是一种广泛应用于工业自动化领域的现场总线标准&#xff0c;它能够实现控制器与现场设备之间的高效通信&#xff0c;常用于连接各种传感器、执行器以及其他工业设备&#xff0c;如机器人、电机驱动器等&#xff0c;具有实时性强、可靠性高的特点。而ModbusTCP…

Linux 安装运行gatk的教程

1.下载安装 wget https://github.com/broadinstitute/gatk/releases/download/4.1.8.1/gatk-4.1.8.1.zip2.解压 unzip *.zip3.查看 gatk --help 如下显示表示安装成功&#xff1a; 注意&#xff1a;仅限在该包所在位置的路径下能使用

使用Xilinx PCIE XDMA框架读写访问DDR3内容

在 FPGA 开发中&#xff0c;使用 XDMA&#xff08;PCIe DMA&#xff09;是实现主机和 FPGA 之间数据传输的常见方法。xdma_rw.exe 是一个官方提供的命令行工具&#xff0c;用于与 FPGA 进行读写操作&#xff0c;支持从 PCIe 总线读取或写入数据。我利用xdma框架实现了DDR3内存的…

【论文笔记之 Mega-TTS2】Boosting Prompting Mechanisms For Zero-Shot Speech Synthesis

本文对 Ziyue Jiang 等人于 2024 年发表的论文进行简单地翻译。如有表述不当之处欢迎批评指正。欢迎任何形式的转载&#xff0c;但请务必注明出处。 论文链接&#xff1a;https://arxiv.org/pdf/2307.07218 目录 Abstract1. 介绍2. 背景3. 方法3.1. 解耦出韵律和音色3.2. 压缩…

haproxy+nginx负载均衡实验

准备三台虚拟机&#xff1a; HAProxy 服务器192.168.65.131Web 服务器 1192.168.65.132Web 服务器 2192.168.65.133 在 HAProxy 服务器&#xff08;192.168.65.131&#xff09;上操作&#xff1a; 安装 HAProxy&#xff1a; sudo yum install -y haproxy编辑 HAProxy 配置…

[论文阅读] (34)ESWA2024 基于SGDC的轻量级入侵检测系统

《娜璋带你读论文》系列主要是督促自己阅读优秀论文及听取学术讲座&#xff0c;并分享给大家&#xff0c;希望您喜欢。由于作者的英文水平和学术能力不高&#xff0c;需要不断提升&#xff0c;所以还请大家批评指正&#xff0c;非常欢迎大家给我留言评论&#xff0c;学术路上期…

华三交换机怎么进行链路聚合?

目录 准备&#xff1a;两台交换机 配置&#xff1a;进行交换机配置 完成&#xff1a;检查链路聚合是否成功 准备&#xff1a;两台交换机 1、进行连线 2、上行Core交换机都选取 Ten-GigabitEthernet1/0/51、Ten-GigabitEthernet1/0/52和 Ten-GigabitEthernet2/0/51、Ten-Giga…

【无线传感网】无线传感器网络覆盖技术

文章目录 覆盖算法设计思路及性能评价标准覆盖感知模型布尔感知模型概率感知模型 无线传感网络覆盖算法分类按照配置方式确定性覆盖随机性覆盖 根据覆盖目标面覆盖点覆盖栅栏覆盖 典型的WSN覆盖算法与协议基于网格的覆盖定位传感器配置算法圆周覆盖连通传感器覆盖轮换活跃/休眠…

积分图(Integral Image)与均值滤波的快速实现

积分图&#xff08;Integral Image&#xff09;也称为求和图&#xff08;Summed Area Table&#xff09;&#xff0c;是一种用于快速计算图像中任意矩形区域像素值总和的技术。 基本概念 积分图的每个位置(i, j)存储的是从图像左上角(1, 1)到当前位置(i, j)所有像素值的累积和…

MySQL数据库笔记——多版本并发控制MVCC

大家好&#xff0c;这里是Good Note&#xff0c;关注 公主号&#xff1a;Goodnote&#xff0c;本文详细介绍MySQL的并发控制&#xff1a;多版本并发控制MVCC。 文章目录 背景介绍数据库并发控制——锁机制悲观锁和乐观锁悲观锁乐观锁 数据库并发控制——MVCC 的引入MVCC 和锁机…

css3实现文字下滑波浪线

上效果 上菜 text-decoration 属性作用&#xff1a;用于设置或检索文本的装饰线&#xff0c;如下划线、上划线、删除线等 text-decoration: line || color || style; 参数&#xff1a; line: 指定装饰线类型&#xff0c;如 underline&#xff08;下划线&#xff09;、overline&…