Java的反射机制中,用Class的getField(String name)或getDelaredField(String name)可以得到目标类的指定属性,返回类型是Field。
在看它们的区别之前先看下它们的源码(英文部分自己翻译了下):
/**
* Returns a {@code Field} object that reflects the specified public member
* field of the class or interface represented by this {@code Class}
* object. The {@code name} parameter is a {@code String} specifying the
* simple name of the desired field.
*
* 返回一个域对象,反射出这个类对象所代表的类或接口的指定的Public 域成员。
* 名称参数是由字符串所指定的期望域的简单名称
* <p> The field to be reflected is determined by the algorithm that
* follows. Let C be the class or interface represented by this object:
*
* 这个域被如下的算法所决定。C是这个对象所代表的类或者接口
* <OL>
* <LI> If C declares a public field with the name specified, that is the
* field to be reflected.</LI>
* 如果C声明一个由指定名称的公共域,那就是要被反射的域
* <LI> If no field was found in step 1 above, this algorithm is applied
* recursively to each direct superinterface of C. The direct
* superinterfaces are searched in the order they were declared.</LI>
* 如果在步骤1中没有域被找到,这个算法将递归应用到每个C的父接口中。直接的父接口
* 将由声明顺序遍历查找。
* <LI> If no field was found in steps 1 and 2 above, and C has a
* superclass S, then this algorithm is invoked recursively upon S.
* If C has no superclass, then a {@code NoSuchFieldException}
* is thrown.</LI>
* </OL>
* 如果在步骤1和步骤2中,没有域被找到,C有一个父类型S,然后这个算法将被在S上递归调用。
* 如果C没有父类,则会抛出NoSuchFieldException的异常
* <p> If this {@code Class} object represents an array type, then this
* method does not find the {@code length} field of the array type.
*
* 如果这个类对象代表一个数组类型,那么这个方法将找不到这个数组类型的length域
* @param name the field name
* @return the {@code Field} object of this class specified by
* {@code name}
* @throws NoSuchFieldException if a field with the specified name is
* not found.
* @throws NullPointerException if {@code name} is {@code null}
* @throws SecurityException
* If a security manager, <i>s</i>, is present and
* the caller's class loader is not the same as or an
* ancestor of the class loader for the current class and
* invocation of {@link SecurityManager#checkPackageAccess
* s.checkPackageAccess()} denies access to the package
* of this class.
*
* @since JDK1.1
* @jls 8.2 Class Members
* @jls 8.3 Field Declarations
*/
@CallerSensitive
public Field getField(String name)
throws NoSuchFieldException, SecurityException {
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true);
Field field = getField0(name);
if (field == null) {
throw new NoSuchFieldException(name);
}
return field;
}
/**
* Returns a {@code Field} object that reflects the specified declared
* field of the class or interface represented by this {@code Class}
* object. The {@code name} parameter is a {@code String} that specifies
* the simple name of the desired field.
*
*返回一个域对象,反射出这个类对象所代表的类或接口所声明的所有域成员。
* 名称参数是由字符串所指定的期望域的简单名称
* <p> If this {@code Class} object represents an array type, then this
* method does not find the {@code length} field of the array type.
*
*如果这个类对象代表一个数组类型,那么这个方法将找不到这个数组类型的length域
* @param name the name of the field
* @return the {@code Field} object for the specified field in this
* class
* @throws NoSuchFieldException if a field with the specified name is
* not found.
* @throws NullPointerException if {@code name} is {@code null}
* @throws SecurityException
* If a security manager, <i>s</i>, is present and any of the
* following conditions is met:
*
* <ul>
*
* <li> the caller's class loader is not the same as the
* class loader of this class and invocation of
* {@link SecurityManager#checkPermission
* s.checkPermission} method with
* {@code RuntimePermission("accessDeclaredMembers")}
* denies access to the declared field
*
* <li> the caller's class loader is not the same as or an
* ancestor of the class loader for the current class and
* invocation of {@link SecurityManager#checkPackageAccess
* s.checkPackageAccess()} denies access to the package
* of this class
*
* </ul>
*
* @since JDK1.1
* @jls 8.2 Class Members
* @jls 8.3 Field Declarations
*/
@CallerSensitive
public Field getDeclaredField(String name)
throws NoSuchFieldException, SecurityException {
checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
Field field = searchFields(privateGetDeclaredFields(false), name);
if (field == null) {
throw new NoSuchFieldException(name);
}
return field;
}
getField(String name)只能获取public的字段,包括父类的;
而getDeclaredField(String name)能获取自己声明的各种字段,包括public,protected,private。