Java 反射的基本使用

Java 反射的基本使用

Field 通过获取对应的对象的类声明的字段,可以动态地修改指定对象的一些属性。Field 十分有用, 其中在使用泛型时可以带来很大的便利。

BookChapter 类:

import lombok.AccessLevel;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;

@Data
@NoArgsConstructor(access = AccessLevel.PUBLIC)
public class BookChapter {
    public  Long isbn = 1L;

    private Integer chapterId;

    private Short chapterKind;

    private String chapterName;
}

使用的 JDK 版本(JDK 15):
在这里插入图片描述

  1. 通过对应的类来获取声明的字段属性。
/*
	获取指定类的 class 对象, 在这里是 BookChapter 类
*/
Class<BookChapter> chapterClass = BookChapter.class;
/*
	获取对应类的构造函数, 这要求指定的类有默认的构造函数。即不传入任何参数的构造函数。
	使用 lombok 的 @NoArgsConstructor 注解可以有效地添加对应的无参构造函数。
	当然, 也可以通过在 getConstructor() 中添加对应的构造函数的参数获取指定的构造函数
*/
Constructor<BookChapter> constructor = chapterClass.getConstructor();
/*
	构造一个新的实体对象, 如果获取到的构造函数是带参数的, 那么在这里实例化对象时也必须添加对应的构造函数参数:new Object(){} 的形式
*/
BookChapter obj = constructor.newInstance();
/*
	获取这个类声明的字段属性列表
*/
Field[] fields = chapterClass.getDeclaredFields();
  1. 设置对应的字段属性值
/*
	遍历属性字段,设置对应的属性值
*/
for (Field field: fields) {
	 /*
	 	设置该字段是可以访问的, 感觉很怪。。。。。
	 */
     field.setAccessible(true);
     /*
     	对BookChapter对象字段设置对应的属性值, 由于只是学习, 因此只是使用几个简单的数据验证。
     	对于泛型的字段的属性值的设置, 可以将要设置的字段属性值转变为 Object 类型的对象,
     	由于 Object 是所有类的父类, 因此可以使用 Field的 set 方法设置属性值。
     */
     switch (field.getName()) {
         case "isbn" -> field.set(obj, 123456L);
         case "chapterId" -> field.set(obj, 1);
         case "chapterKind" -> field.set(obj, (short) 1);
         case "chapterName" -> field.set(obj, "Hello World");
         default -> System.out.println("Bad Object");
     }
 }
  1. 查看设置字段属性值后的 BookChapter 对象:
    在这里插入图片描述
     可以看到, 我们的 BookChapter 对象已经被设置了对应的属性值。
  2. Field 的一些其他问题:
    1)关于静态变量的属性值设置
     事实证明, 使用Field可以修改静态变量的属性值, 无论它是用 privateprotectedpublic 访问权限修饰的。但是当使用 final 关键字修饰静态变量时, 尝试通过 Field 修改属性值将会抛出 IllegalAccessException.
    2)关于final 变量的属性值设置
     对于仅仅是final修饰的字段, 通过 Field 是可以修改这个属性字段值的。
    3)关于不同访问控制修饰的属性值的设置
     使用不同的访问权限修饰的属性,使用 Field 依旧是可以随意地修改对应的属性字段值。

 因此, 在使用Field时需要要特别注意, 不像通常使用的 GetterSetter 方法, Field 的使用可能会破坏类的封装性。此外, 由于 final的修饰对于 Field 的没有作用, 因此使用 final关键字的属性在使用Field时一定要将它的访问可访问字段设置为false

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值