反射机制:getDeclaredField和getField的区别说明

 更新时间:2021年06月30日 11:05:35   作者:Apple_羊先森  
这篇文章主要介绍了反射机制:getDeclaredField和getField的区别说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

getDeclaredField和getField区别

在做后台开发时实体的固定字段一般会抽取为一个父类,其他类继承该父类,例如主键字段,会放到一个父类中(IdEntity),其他类继承该类,但是我们在操作时操作的是子类,在通过子类获取父类属性是getDeclaredField和getField是不一样的,简单说

1、getDeclaredFiled 仅能获取类本身的属性成员(包括私有、共有、保护)

2、getField 仅能获取类(及其父类可以自己测试) public属性成员

因此在获取父类的私有属性时,要通过getSuperclass的之后再通过getDeclaredFiled获取。

父类,出去id作为父类字段

import javax.persistence.Column;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass; 
import org.hibernate.annotations.GenericGenerator;
@MappedSuperclass
public abstract class IdEntity {
	private String id; 
	@Id
	@GeneratedValue(generator = "paymentableGenerator")
	@GenericGenerator(name = "paymentableGenerator", strategy = "uuid")
	@Column(name ="ID",nullable=false,length=32)
	public String getId() {
		return id;
	} 
	public void setId(String id) {
		this.id = id;
	} 
}

子类

public class Reflect extends IdEntity { 
 public String publicField;
 private String privateField; 
 public Reflect(String publicField, String privateField) {
  super();
  this.publicField = publicField;
  this.privateField = privateField;
 } 
 public String getPrivateField() {
  return privateField;
 } 
 public void setPrivateField(String privateField) {
  this.privateField = privateField;
 } 
}

测试类:

import java.lang.reflect.Field; 
public class ReflectDemo { 
 /**
  * @Description: TODO
  * @param @param args
  * @return void
  * @throws SecurityException
  * @throws NoSuchFieldException
  * @throws IllegalAccessException
  * @throws IllegalArgumentException
  * @throws
  * @author ydecai
  * @date 2019-1-23
  */
 public static void main(String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
  Reflect re = new Reflect("zhangsan", "lisi");
  re.setId("111");
  //getDeclaredFiled获取本类属性
//  Field publicField = re.getClass().getDeclaredField("publicField");
//  System.out.println(publicField.get(re));
  Field publicField = re.getClass().getField("publicField");
  System.out.println(publicField.get(re));
  //getField获取公有属性,包括父类的,下面语句报错
  //Field privateField = re.getClass().getField("privateField");
  Field privateField = re.getClass().getDeclaredField("privateField");
  privateField.setAccessible(true);
  System.out.println(privateField.get(re));
  //获取父类私有属性并获取值
  Field fileId = re.getClass().getSuperclass().getDeclaredField("id");
  fileId.setAccessible(true);
  System.out.println(fileId.get(re));
 } 
}

getDeclaredField方法与NoSuchFieldException异常

使用getDeclaredField()方法,发现有异常NoSuchFieldException,后续发现是因为实体类使用了extends引起的,就百度了下原因。

发现getDeclaredField()方法只能获取当前类的所有属性,但是不能获取父类的属性

这里引出两个问题

第一个问题:getField()和getDeclaredField()方法是做什么的:

用Class的getField(String name)或getDelaredField(String name)是用来得到目标类的指定属性,返回类型是Field。

第二个问题:getField()和getDeclaredField()方法有什么区别:

getField(String name)只能获取public的字段,包括父类的;

而getDeclaredField(String name)只能获取自己声明的各种字段,包括public,protected,private。

那么解决我遇到的问题有几种方法:

方法1:弃用extends,但是我如果还想继续使用extends怎么办呢,看方法2。

方法2:可以通过getSuperclass()方法获取父类,再调用getDeclaredField()方法。

Field field;
try {
   field = obj.getClass().getDeclaredField(fieldName);
} catch (NoSuchFieldException e) {
   //此处用于解决继承导致的getDeclaredField不能直接获取父类属性的问题
   field = obj.getClass().getSuperclass().getDeclaredField(fieldName);
}
 

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Mybatis-plus4条件构造器使用方式

    Mybatis-plus4条件构造器使用方式

    这篇文章主要介绍了Mybatis-plus4条件构造器使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-02-02
  • java对象转化成String类型的四种方法小结

    java对象转化成String类型的四种方法小结

    在java项目的实际开发和应用中,常常需要用到将对象转为String这一基本功能。本文就详细的介绍几种方法,感兴趣的可以了解一下
    2021-08-08
  • 一篇文章带你理解Java的SPI机制(图文并茂)

    一篇文章带你理解Java的SPI机制(图文并茂)

    本文详细介绍了Java的SPI机制,包括其定义、用途和实现方式,SPI(ServiceProviderInterface)是一种服务发现机制,用于实现框架或库的扩展点,文中通过代码介绍的非常详细,需要的朋友可以参考下
    2024-10-10
  • Java实现图片上文字内容的动态修改的操作步骤

    Java实现图片上文字内容的动态修改的操作步骤

    在数字图像处理领域,Java提供了强大的库来处理图片,包括读取、修改和写入图片,如果你需要在Java应用程序中修改图片上的文字内容,可以通过图像处理技术来实现,这篇博文将介绍如何使用Java实现图片上文字内容的动态修改,需要的朋友可以参考下
    2024-07-07
  • 链表的原理及java实现代码示例

    链表的原理及java实现代码示例

    这篇文章主要介绍了链表的原理及java实现代码示例,涉及单向链表的基本介绍,单向链表的Java实现代码分享等相关内容,具有一定参考价值,需要的朋友可以参考下。
    2017-11-11
  • Java序列化原理详解

    Java序列化原理详解

    这篇文章主要介绍了Java序列化原理详解,文章围绕主题展开详细的内容介绍,具有一定的参考价值,感兴趣的小伙伴可以参考一下
    2022-06-06
  • spring boot使用thymeleaf为模板的基本步骤介绍

    spring boot使用thymeleaf为模板的基本步骤介绍

    Spring Boot项目的默认模板引擎是Thymeleaf,这没什么好说的,个人觉得也非常好,下面这篇文章主要给大家介绍了关于spring boot使用thymeleaf为模板的相关资料,需要的朋友可以参考借鉴,下面来一起学习学习吧。
    2018-01-01
  • JAVA HashSet和TreeSet 保证存入元素不会重复的操作

    JAVA HashSet和TreeSet 保证存入元素不会重复的操作

    这篇文章主要介绍了JAVA HashSet和TreeSet 保证存入元素不会重复的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-09-09
  • idea创建包含多个springboot module的maven project的方法

    idea创建包含多个springboot module的maven project的方法

    这篇文章主要介绍了idea创建包含多个springboot module的maven project的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-09-09
  • SpringBoot如何实现文件下载

    SpringBoot如何实现文件下载

    这篇文章主要介绍了SpringBoot如何实现文件下载问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11

最新评论