首页 > 编程语言 >Java 类之 java.lang.reflect.Field

Java 类之 java.lang.reflect.Field

时间:2023-12-14 11:04:39浏览次数:36  
标签:lang Java 获取 System Field 字段 注解 println java


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 异常。
  1. getFields()
  • 获取该类及其父类中所有公有字段的数组。
  • 返回一个 Field 对象数组。

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

  1. getDeclaredField(String name)
  • 获取该类中指定名称的任意访问权限的字段,包括私有字段。
  • 如果字段不存在,则抛出 NoSuchFieldException 异常。
  1. 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 对象,该对象反映了指定声明字段的类或接口。
  1. 获取所有字段:
  • Class.getFields(): 返回一个包含某个类或接口的所有公有字段的数组。
  • Class.getDeclaredFields(): 返回一个包含某个类或接口的所有字段的数组,包括私有字段。
  1. 操作字段:
  • Field.get(Object obj): 返回指定对象上此 Field 表示的字段的值。
  • Field.set(Object obj, Object value): 将指定对象上此 Field 表示的字段设置为指定的新值。
  1. 字段信息获取:
  • Field.getName(): 返回字段的名称。
  • Field.getType(): 返回字段的类型(Class 对象)。
  • Field.getModifiers(): 返回表示字段修饰符的整数。
  1. 访问字段修饰符:
  • Modifier.toString(int modifiers): 将修饰符转换为字符串形式。
  1. 设置可访问性:
  • 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。
  1. 获取所有注解:
  • Annotation[] getAnnotations(): 返回包含此元素上存在的所有注解的数组。
  • Annotation[] getDeclaredAnnotations(): 返回直接存在于此元素上的所有注解的数组,与继承的注解无关。
  1. 判断是否存在指定类型的注解:
  • 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 方法时的细微差别,根据需求选择合适的方法。


标签:lang,Java,获取,System,Field,字段,注解,println,java
From: https://blog.51cto.com/u_13272819/8815680

相关文章

  • Java 类之 java.lang.System
    Java类之java.lang.System文章目录Java类之java.lang.System一、简介二、主要功能1、`currentTimeMillis()`-获取当前时间的毫秒数说明代码示例2、`getProperty(Stringkey)`-获取系统属性说明代码示例3、`exit(intstatus)`-终止虚拟机说明代码示例4、`arraycopy(Objec......
  • Java 类之 java.util.Properties
    Java类之java.util.Properties文章目录Java类之java.util.Properties一、简介二、主要功能1、存储键值对2、读取文件与属性代码示例运行结果截图3、设置属性并保存文件代码示例结果截图4、遍历属性代码示例运行结果关联博客:《基于Java列举和说明常用的外部化配置的实现方式......
  • java写个爬虫抓取汽车之家车型配置参数
    前几天有个搞工程的表弟找我,问我什么车好,可以经常跑工地的,看上去又有面子。于是我挥动发财的小手,写一个爬虫程序,筛选并整理了一些数据,并附上下载的图片提供参考,看中了果断第二天提车到手。我是使用Java编写的爬虫程序,用于抓取汽车之家网站上的车型、车系、配置参数数据。以下是每行......
  • Java 大文件分片上传
    原理:前端通过js读取文件,并将大文件按照指定大小拆分成多个分片,并且计算每个分片的MD5值。前端将每个分片分别上传到后端,后端在接收到文件之后验证当前分片的MD5值是否与上传的MD5一致,待所有分片上传完成之后后端将多个分片合并成一个大文件,并校验该文件的MD5值是否与上传时传入的M......
  • 基于JavaWeb的电影推荐平台的设计与实现
     1.项目演示前端演示地址:http://96.8.117.232:8082/后端演示地址:http://96.8.117.232:8083/ (管理员账号:admin密码123456)访问慢是因为服务器是海外的,国内访问慢,便宜VPS凑合了2.项目介绍技术列表技术说明SpringBootWeb应用开发框架Vue3.xjava1.8my......
  • Java-研究HashMap的源码
    Java-研究HashMap的源码JDK版本:17类注释基于哈希表的Map接口实现。此实现提供了所有可选的映射操作,并允许null值和null键。(HashMap类大致相当于Hashtable,只不过它是不同步的并且允许null。)该类不保证映射的顺序;特别是,它不保证顺序随着时间的推移保持不变。此实现为基本操......
  • Java之Hashset的原理及解析
     4.数据结构4.1二叉树【理解】二叉树的特点二叉树中,任意一个节点的度要小于等于2节点:在树结构中,每一个元素称之为节点度:每一个节点的子节点数量称之为度二叉树结构图编辑4.2二叉查找树【理解】二叉查找树的特点二叉查找树,又称二叉排序树或者二叉搜索树每一个节点上最多有两......
  • springboot004旅游路线规划系统(Java毕业设计,附数据库和源码)
    第一章绪论1.1选题背景与研究意义随着社会的不断进步,在居民生活水平提高的同时,人们当前在生活的方方面面也越来越注重服务所带来的体验,随着近几年国家政策大力发展旅游业,旅游景点的建设越来也完善,旅游业的发展速度得到了显著的提升。各大旅行社、旅游景点都不断的推出新的活动计......
  • Java从入门到放弃(知识体系图谱)
    一、Java学习路线话不多说,先来一张劝退图!!!二、Java并发学习路线下面是一张关于Java并发编程的思维导图,大的方向可以分为三个部分:线程基础、理论基础、工具类JUC三、Java虚拟机一张关于JVM的思维导图,大的方向可以分为三个部分:字节码与类的加载、内存与垃圾回收、性能监......
  • 关于java的多态方法调用顺序的问题
    使用父类类型的引用指向子类的对象,该引用调用的师父类中定义的方法和变量,变量不能被重写(覆盖);如果子类中重写了父类中的一个方法,那么在调用这个方法的时候,将会调用子类中的这个方法;注意特殊情况,如果该父类引用所调用的方法参数列表未定义,就调用该父类的父类中查找,如果还没找到就强......