getDeclaredField和getField区别
在做后台开发时实体的固定字段一般会抽取为一个父类,其他类继承该父类,例如主键字段,会放到一个父类中(IdEntity),其他类继承该类,但是我们在操作时操作的是子类,在通过子类获取父类属性是getDeclaredField和getField是不一样的,简单说
1、getDeclaredFiled 仅能获取类本身的属性成员(包括私有、共有、保护)
2、getField 仅能获取类(及其父类可以自己测试) public属性成员
因此在获取父类的私有属性时,要通过getSuperclass的之后再通过getDeclaredFiled获取。
父类,出去id作为父类字段
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
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;
}
}
|
子类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
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;
}
}
|
测试类:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
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()方法。
1
2
3
4
5
6
7
|
Field field;
try {
field = obj.getClass().getDeclaredField(fieldName);
} catch (NoSuchFieldException e) {
//此处用于解决继承导致的getDeclaredField不能直接获取父类属性的问题
field = obj.getClass().getSuperclass().getDeclaredField(fieldName);
}
|
以上为个人经验,希望能给大家一个参考,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/caicaimaomao/article/details/86611897