好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

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

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

查看更多关于反射机制:getDeclaredField和getField的区别说明的详细内容...

  阅读:25次