Java Class.getField()/getDeclaredField()返回成员变量

Class.getField()返回已加载类声明的所有public成员变量的Field对象,包括从父类继承过来的成员变量,参数name指定成员变量的名称。

Class.getDeclaredField()返回当前类所有成员变量。

定义

Field getField(String name)
Field getDeclaredField(String name)

源码

public Field getDeclaredField(String name) throws NoSuchFieldException,SecurityException 
{
    checkMemberAccess(Member.DECLARED, ClassLoader.getCallerClassLoader());
    Field field = searchFields(privateGetDeclaredFields(false), name);
    if (field == null) {
        throw new NoSuchFieldException(name);
    }
    return field;
}
Private Field getField0(String name) throws NoSuchFieldException {  
       Field res = null;  
       // Search declared public fields  
       if ((res = searchFields(privateGetDeclaredFields(true), name)) != null) {  
           return res;  
       }  
...... 

getField其实调用的是getField0,他们最后都调用了searchFields,不过getDeclaredField传入的是privateGetDeclaredFields(false), getField传入的是privateGetDeclaredFields(true)。

例子

package cn.com.vo;
public class Father {
    public String name = "父亲";

    public String sex = "男";

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }
} === ======================================

package cn.com.vo;
public class Son extends Father {
    //public String name;
    public int age = 20;
} === ======================================package cn.com.vo;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import cn.com.vo.UserVo;
public class TestReflect {
    /**
* java反射机制
*/
    public static void main(String[] args) {
        try {
            //类的动态加载
            Class c = Class.forName("cn.com.vo.Son"); //方式一
            Son vo = (Son) c.newInstance();

            Field f = c.getField("name");
            System.out.println(f.get(vo));

            //注意:下段代码会报错,
            /*Field f2=c.getDeclaredField("name");
    System.out.println(f2.get(vo));*/
        } catch(ClassNotFoundException e) {
            e.printStackTrace();
        } catch(SecurityException e) {
            e.printStackTrace();
        } catch(NoSuchFieldException e) {
            e.printStackTrace();
        } catch(InstantiationException e) {
            e.printStackTrace();
        } catch(IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}

总结

1. getDeclaredField是可以获取一个类本身的所有字段. getField只能获取类及其父类的public 字段. 
2. 如果想要获取父类的所有成员变量(主要是为了拿到私有成员变量,只想获取公有成员变量可以直接使用getField),可以通过取得当前类的父类的class对象再调用getDeclaredField方法。

版权声明:本文为JAVASCHOOL原创文章,未经本站允许不得转载。