Java 类之 java.lang.reflect.Field

Java 类之 java.lang.reflect.Field

文章目录

  • Java 类之 java.lang.reflect.Field
  • 一、概述
    • 1、java.lang.Class 类获取字段的方法
      • 获取全部公有字段(含继承的,不含私有的)
      • 获取本类的所有字段(不含继承的,含私有的)
      • 代码示例
    • 2、java.lang.reflect.Field 类简介
    • 3、类定义信息
  • 二、基本功能
    • 1、基本功能
    • 2、代码示例
  • 三、扩展
    • 1、关于注解的方法
    • 2、`getAnnotations()` 与 `getDeclaredAnnotations()` 的区别
      • `getAnnotation` 方法
      • `getDeclaredAnnotation` 方法
    • 3、其他注意点

一、概述

1、java.lang.Class 类获取字段的方法

获取全部公有字段(含继承的,不含私有的)

  1. getField(String name)
    • 获取该类及其父类指定名称的公有字段。
    • 如果字段不存在,则抛出 NoSuchFieldException 异常。
  2. getFields()
    • 获取该类及其父类中所有公有字段的数组。
    • 返回一个 Field 对象数组。

获取本类的所有字段(不含继承的,含私有的)

  1. getDeclaredField(String name)
    • 获取该类中指定名称的任意访问权限的字段,包括私有字段。
    • 如果字段不存在,则抛出 NoSuchFieldException 异常。
  2. getDeclaredFields()
    • 获取该类中所有声明的字段,包括私有字段。
    • 返回一个 Field 对象数组。

代码示例

// 获取公有字段(含继承的,不含私有的)
Field publicField = MyClass.class.getField("publicField");
System.out.println("Public Field: " + publicField);// 获取所有公有字段(含继承的,不含私有的)
Field[] publicFields = MyClass.class.getFields();
System.out.println("All Public Fields: ");
for (Field field : publicFields) {System.out.println(field);
}// 获取本类的私有字段(不含继承的,含私有的)
Field privateField = MyClass.class.getDeclaredField("privateField");
System.out.println("Private Field: " + privateField);// 获取本类的所有字段(不含继承的,含私有的)
Field[] allFields = MyClass.class.getDeclaredFields();
System.out.println("All Fields: ");
for (Field field : allFields) {System.out.println(field);
}

2、java.lang.reflect.Field 类简介

java.lang.reflect.Field 类是 Java 反射机制中用于表示类的字段(成员变量)的类。它提供了一种在运行时获取和操作类的字段的方式。

3、类定义信息

public final class Field extends AccessibleObject implements Member

二、基本功能

1、基本功能

  1. 获取字段对象:
    • Class.getField(String name): 返回一个 Field 对象,该对象反映了指定公有字段的类或接口。
    • Class.getDeclaredField(String name): 返回一个 Field 对象,该对象反映了指定声明字段的类或接口。
  2. 获取所有字段:
    • Class.getFields(): 返回一个包含某个类或接口的所有公有字段的数组。
    • Class.getDeclaredFields(): 返回一个包含某个类或接口的所有字段的数组,包括私有字段。
  3. 操作字段:
    • Field.get(Object obj): 返回指定对象上此 Field 表示的字段的值。
    • Field.set(Object obj, Object value): 将指定对象上此 Field 表示的字段设置为指定的新值。
  4. 字段信息获取:
    • Field.getName(): 返回字段的名称。
    • Field.getType(): 返回字段的类型(Class 对象)。
    • Field.getModifiers(): 返回表示字段修饰符的整数。
  5. 访问字段修饰符:
    • Modifier.toString(int modifiers): 将修饰符转换为字符串形式。
  6. 设置可访问性:
    • Field.setAccessible(boolean flag): 设置字段的可访问性。如果字段是私有的,需要设置为 true 才能访问。

2、代码示例

import java.lang.reflect.Field;public class FieldExample {public String publicField;private int privateField;public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {FieldExample obj = new FieldExample();// 获取公有字段对象Field publicField = FieldExample.class.getField("publicField");System.out.println("Public Field: " + publicField);// 获取私有字段对象Field privateField = FieldExample.class.getDeclaredField("privateField");System.out.println("Private Field: " + privateField);// 获取字段的名称、类型和修饰符System.out.println("Field Name: " + publicField.getName());System.out.println("Field Type: " + publicField.getType());System.out.println("Field Modifiers: " + publicField.getModifiers());// 获取并设置公有字段值publicField.set(obj, "Hello, Public Field!");System.out.println("Public Field Value: " + publicField.get(obj));// 获取并设置私有字段值(需要设置可访问性)privateField.setAccessible(true);privateField.set(obj, 42);System.out.println("Private Field Value: " + privateField.get(obj));}
}

三、扩展

1、关于注解的方法

  1. 获取指定类型的注解:
    • Annotation getAnnotation(Class<? extends Annotation> annotationClass): 返回指定类型的注解对象,如果字段没有指定类型的注解,则返回 null。
  2. 获取所有注解:
    • Annotation[] getAnnotations(): 返回包含此元素上存在的所有注解的数组。
    • Annotation[] getDeclaredAnnotations(): 返回直接存在于此元素上的所有注解的数组,与继承的注解无关。
  3. 判断是否存在指定类型的注解:
    • boolean isAnnotationPresent(Class<? extends Annotation> annotationClass): 如果指定类型的注解存在于此元素上,则返回 true。

2、getAnnotations()getDeclaredAnnotations() 的区别

getAnnotation 方法

  • 该方法用于获取指定类型的注解,如果该注解不存在于该字段上,则返回 null
  • 如果注解存在于该字段上,且是继承关系的,该方法会沿着继承链一直找到最终的注解
  • 这个方法也会考虑到注解的继承,即如果指定类型的注解不存在于当前字段上,但存在于该字段的父类或父接口上,也会被返回。

getDeclaredAnnotation 方法

  • 该方法用于获取指定类型的注解,如果该注解不存在于该字段上,则返回 null
  • getAnnotation 不同的是,getDeclaredAnnotation 不会考虑继承关系,只会在当前字段上查找指定类型的注解

3、其他注意点

访问控制: 如果字段是私有的,确保在使用前调用 setAccessible(true) 方法,以便绕过访问控制检查。否则,在访问私有字段时可能会抛出 IllegalAccessException 异常。

field.setAccessible(true);

静态字段: 如果操作的是静态字段,可以将对象设置为 null,而不需要创建实例。

field.set(null, value); // 设置静态字段
Object value = field.get(null); // 获取静态字段的值

字段类型检查: 在设置字段值之前,最好进行类型检查,以确保所设置的值与字段的类型相匹配。否则,在运行时可能会抛出 IllegalArgumentException

if (field.getType() == int.class) {field.setInt(object, 42);
}

异常处理: 在使用反射操作字段时,要考虑可能抛出的异常,如 NoSuchFieldExceptionIllegalAccessException 等。适当地进行异常处理是很重要的。

try {Field field = MyClass.class.getDeclaredField("fieldName");// 其他操作
} catch (NoSuchFieldException | IllegalAccessException e) {e.printStackTrace();
}

性能影响: 反射操作相比直接访问字段的性能较差。如果性能是一个关键问题,考虑使用其他手段,如直接访问字段或者使用生成的代码(如使用字节码增强库)。

字段注解: 如果你使用注解,注意使用 getAnnotationgetDeclaredAnnotation 方法时的细微差别,根据需求选择合适的方法。

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

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

相关文章

去掉表格里某一列单元格的所有后缀

根据代码 import pandas as pd# 加载数据 file_path your_data_file.csv # 替换为您的文件路径 data pd.read_csv(file_path)# 去掉 name 列中所有单元格的 .jpg 后缀 data[name] data[name].str.replace(.jpg, , regexFalse)# 显示修改后的前几行数据 print(data.head())#…

vue下载xlsx表格

vue下载xlsx表格 // 导入依赖库 import XLSX from xlsx; import FileSaver from file-saver; methods:{btn(){let date new Date()let Y date.getFullYear() -let M (date.getMonth() 1 < 10 ? 0 (date.getMonth() 1) : date.getMonth() 1) -let D (date.getDat…

【设备树添加节点】

节点结束位置都需要加分号 of_iomap 完成映射 of_property_read_u32_array of_property_read_string of_fine_node_by_path

如何优雅的避免空指针异常

文章目录 1.数据准备2.实战&#xff1a;获取用户所在的城市2.1.直接获取&#xff1b;容易出现空指针异常。2.2.使用if-else判断&#xff1b;避免了出现空指针的问题&#xff0c;但是代码结构层次嵌套多&#xff0c;不美观2.3.使用工具类美化一下if判断代码2.4.使用Optional解决…

MySQL数据库:开源且强大的关系型数据库管理系统

大家好&#xff0c;我是咕噜-凯撒&#xff0c;数据在当今信息化时代的重要性不可忽视。作为企业和组织的重要资产&#xff0c;数据的管理和存储变得至关重要&#xff0c;MySQL作为一种关系型数据库管理系统&#xff0c;具有非常多的优势&#xff0c;下面简单的探讨一下MySQL数据…

Linux文本处理工具awk用法总结

awk是一种文本处理工具&#xff0c;它逐行读取输入文本&#xff0c;根据用户提供的模式匹配特定的行&#xff0c;然后执行对应的动作来处理匹配到的行。 在处理过程中&#xff0c;awk 将文本行分割成多个字段&#xff0c;并提供了丰富的内置函数和控制结构来处理和操作这些字段…

基于卷尾猴算法优化概率神经网络PNN的分类预测 - 附代码

基于卷尾猴算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于卷尾猴算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于卷尾猴优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神经网络…

【Java程序员面试专栏 专业技能篇】Java SE核心面试指引(二):面向对象思想

关于Java SE部分的核心知识进行一网打尽,包括四部分:基础知识考察、面向对象思想、核心机制策略、Java新特性,通过一篇文章串联面试重点,并且帮助加强日常基础知识的理解,全局思维导图如下所示 本篇Blog为第二部分:面向对象思想,子节点表示追问或同级提问 面向对象基…

按照指定条件对数据进行分组并对每个分组内的全部数据应用自定义函数进行聚合计算groupby().apply()

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 按照指定条件对数据进行分组 并对每个分组内的全部数据 应用自定义函数进行聚合计算 groupby().apply() [太阳]选择题 下列输出正确的是&#xff1a; import pandas as pd data {Name: [A, B,…

.net对接阿里云CSB服务

public Response<string> Main(MonthPlanRequest request){string apiName "MonthPlan", postData request.ToJson(); var result ConnectCSB(apiName, postData);return InvokeResult.Fail<string>("访问成功");}/// <summary>///…

多线程的概念

点击链接返回标题-> 什么是进程&#xff1f; 进程&#xff08;Process&#xff09;&#xff0c;是程序的基本执行实体。 在早期面向进程设计的计算机结构中&#xff0c;进程是程序的基本执行实体&#xff1b; 在当代面向线程设计的计算机结构中&#xff0c;进程是线程的容器…

求二叉树中指定节点所在的层数(可运行)

运行环境.cpp 我这里设置的是查字符e的层数&#xff0c;大家可以在main函数里改成自己想查的字符。&#xff08;输入的字符一定是自己树里有的&#xff09;。 如果没有输出结果&#xff0c;一定是建树错误&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&…

Maven环境配置

Maven环境配置 下载Maven 网址&#xff1a;https://maven.apache.org/download.cgi 如果你的系统是Windows的直接按照箭头指示下载即可 环境变量配置 配置环境变量&#xff1a;将 Maven 的安装目录添加到您的系统环境变量中。 右键点击“我的电脑”&#xff08;或“此电脑…

Startdrive中上传参数设置的具体方法和注意事项

Startdrive中上传参数设置的具体方法和注意事项 适用于配 SINAMICS S120、G130、G150、S150和MV(基于CU3x0-2的驱动器)和所有启动驱动器版本INAMICS G115D/G120/G120D/G120C/G120P/G110M(基于CU2x0-2的驱动器) 根据SINAMICS类型的不同,Startdrive中的Upload参数有所不同。…

leetcode刷题详解——粉刷房子

1. 题目链接&#xff1a;LCR 091. 粉刷房子 2. 题目描述&#xff1a; 假如有一排房子&#xff0c;共 n 个&#xff0c;每个房子可以被粉刷成红色、蓝色或者绿色这三种颜色中的一种&#xff0c;你需要粉刷所有的房子并且使其相邻的两个房子颜色不能相同。 当然&#xff0c;因为…

Ubuntu20上离线安装samba

如果联网&#xff0c;一条 sudo apt-get install samba就可能解决问题&#xff0c;但是没有网&#xff0c;那么只能一个一个的解决问题&#xff1a; 我以为装了samba-common就可以了&#xff0c;发现smbd.serverice not found,于是开始了漫长的下载依赖包&#xff0c;安装&…

Linux中Team链路聚合配置

目录 一、Team介绍 二、网卡的bonding和Teaming技术 三、Teaming常用工作模式 四、实验环境 五、添加物理网卡 1、给虚拟机新增四张物理网卡 2、查看网卡信息 六、Team链路聚合配置 1、创建team0的网络接口 2、为team0设置静态IP,掩码位&#xff0c;网关&#xff0c;dns…

【Django-01】 视图函数和视图类

视图函数 作用详解视图函数的特点视图类实际开发怎么用一个无意义的demo 作用 用于返回给前端数据详解 def list(request):"""1.普通的视图函数 request是HttpRequest 函数2.且必须用request.GET|request.POST 指定方法是什么方法3.返回值不能用 rest_framewor…

25 - 单例模式:如何创建单一对象优化系统性能?

从这一讲开始&#xff0c;我们将一起探讨设计模式的性能调优。在《Design Patterns: Elements of Reusable Object-Oriented Software》一书中&#xff0c;有 23 种设计模式的描述&#xff0c;其中&#xff0c;单例设计模式是最常用的设计模式之一。无论是在开源框架&#xff0…

Java并发编程第12讲——cancelAcquire()流程详解及acquire方法总结

上篇文章介绍了AQS的设计思想以及独占式获取和释放同步状态的源码分析&#xff0c;但是还不够&#xff0c;一是感觉有点零零散散&#xff0c;二是里面还有很多细节没介绍到——比如cancelAcquire()方法&#xff08;重点&#xff09;&#xff0c;迫于篇幅原因&#xff0c;今天就…