反射機制:getDeclaredField和getField的區(qū)別說明
getDeclaredField和getField區(qū)別
在做后臺開發(fā)時實體的固定字段一般會抽取為一個父類,其他類繼承該父類,例如主鍵字段,會放到一個父類中(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()方法,發(fā)現(xiàn)有異常NoSuchFieldException,后續(xù)發(fā)現(xiàn)是因為實體類使用了extends引起的,就百度了下原因。
發(fā)現(xiàn)getDeclaredField()方法只能獲取當前類的所有屬性,但是不能獲取父類的屬性

這里引出兩個問題
第一個問題:getField()和getDeclaredField()方法是做什么的:
用Class的getField(String name)或getDelaredField(String name)是用來得到目標類的指定屬性,返回類型是Field。
第二個問題:getField()和getDeclaredField()方法有什么區(qū)別:
getField(String name)只能獲取public的字段,包括父類的;
而getDeclaredField(String name)只能獲取自己聲明的各種字段,包括public,protected,private。
那么解決我遇到的問題有幾種方法:
方法1:棄用extends,但是我如果還想繼續(xù)使用extends怎么辦呢,看方法2。
方法2:可以通過getSuperclass()方法獲取父類,再調(diào)用getDeclaredField()方法。
Field field;
try {
field = obj.getClass().getDeclaredField(fieldName);
} catch (NoSuchFieldException e) {
//此處用于解決繼承導致的getDeclaredField不能直接獲取父類屬性的問題
field = obj.getClass().getSuperclass().getDeclaredField(fieldName);
}
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
Spring Boot mybatis-config 和 log4j 輸出sql 日志的方式
這篇文章主要介紹了Spring Boot mybatis-config 和 log4j 輸出sql 日志的方式,本文通過實例圖文相結合給大家介紹的非常詳細,需要的朋友可以參考下2021-07-07
IDEA 集成log4j將SQL語句打印在控制臺上的實現(xiàn)操作
這篇文章主要介紹了IDEA 集成log4j將SQL語句打印在控制臺上的實現(xiàn)操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-02-02
idea中創(chuàng)建jsp項目的詳細實戰(zhàn)步驟
才學javaWeb,以防自己忘記創(chuàng)建項目的過程,所以淺淺的記錄一下吧,下面這篇文章主要給大家介紹了關于idea中創(chuàng)建jsp項目的詳細步驟,文中通過圖文介紹的非常詳細,需要的朋友可以參考下2022-09-09
Java Lambda表達式與匿名內(nèi)部類的聯(lián)系和區(qū)別實例分析
這篇文章主要介紹了Java Lambda表達式與匿名內(nèi)部類的聯(lián)系和區(qū)別,結合實例形式分析了Java Lambda表達式與匿名內(nèi)部類功能、用法、區(qū)別及操作注意事項,需要的朋友可以參考下2019-10-10
window?下?win10?jdk8安裝與環(huán)境變量的配置過程
這篇文章主要介紹了window?下?win10?jdk8安裝與環(huán)境變量的配置,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-08-08

