我们知道在Java的反射机制中,最核心的一个类就是Class类。
Class类中提供了两个常用的获取类的成员变量的方法。
方法1 getFields()
/*** Returns an array containing {@codeField} objects reflecting all
* the accessible public fields of the class or interface represented by
* this {@codeClass} object.
*
*
If this {@codeClass} object represents a class or interface with no
* no accessible public fields, then this method returns an array of length
* 0.
*
*
If this {@codeClass} object represents a class, then this method
* returns the public fields of the class and of all its superclasses.
*
*
If this {@codeClass} object represents an interface, then this
* method returns the fields of the interface and of all its
* superinterfaces.
*
*
If this {@codeClass} object represents an array type, a primitive
* type, or void, then this method returns an array of length 0.
*
*
The elements in the returned array are not sorted and are not in any
* particular order.
*
*@returnthe array of {@codeField} objects representing the
* public fields
*@throwsSecurityException
* If a security manager, s, 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 {@linkSecurityManager#checkPackageAccess
* s.checkPackageAccess()} denies access to the package
* of this class.
*
*@sinceJDK1.1
* @jls 8.2 Class Members
* @jls 8.3 Field Declarations*/@CallerSensitivepublic Field[] getFields() throwsSecurityException {
checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(),true);return copyFields(privateGetPublicFields(null));
}
从注释上可以看出来,这个方法是用来获取一个类和其所有父类中被public修饰符修饰的成员变量的。
方法2 getDeclaredFields()
/*** Returns an array of {@codeField} objects reflecting all the fields
* declared by the class or interface represented by this
* {@codeClass} object. This includes public, protected, default
* (package) access, and private fields, but excludes inherited fields.
*
*
If this {@codeClass} object represents a class or interface with no
* declared fields, then this method returns an array of length 0.
*
*
If this {@codeClass} object represents an array type, a primitive
* type, or void, then this method returns an array of length 0.
*
*
The elements in the returned array are not sorted and are not in any
* particular order.
*
*@returnthe array of {@codeField} objects representing all the
* declared fields of this class
*@throwsSecurityException
* If a security manager, s, is present and any of the
* following conditions is met:
*
*
*
*
the caller's class loader is not the same as the* class loader of this class and invocation of
* {@linkSecurityManager#checkPermission
* s.checkPermission} method with
* {@codeRuntimePermission("accessDeclaredMembers")}
* denies access to the declared fields within this class
*
*
the caller's class loader is not the same as or an* ancestor of the class loader for the current class and
* invocation of {@linkSecurityManager#checkPackageAccess
* s.checkPackageAccess()} denies access to the package
* of this class
*
*
*
*@sinceJDK1.1
* @jls 8.2 Class Members
* @jls 8.3 Field Declarations*/@CallerSensitivepublic Field[] getDeclaredFields() throwsSecurityException {
checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(),true);return copyFields(privateGetDeclaredFields(false));
}
从注释上可以看出来,这个方法是用来获取一个类中的所有成员变量的,即包括被public、protected、defautl和private修饰符修饰的所有成员变量。
但是这个方法,其基类的一个成员变量都不会拿得到。
取本类和基类的所有成员变量
要取本类和基类的所有成员变量,Class类中提供的两种获取类中成员变量的方法都不能直接实现这个需求,但是可以通过简单的while循环来实现。
//取所有字段(包括基类的字段)
Field[] allFields =clazz.getDeclaredFields();
Class superClass=clazz.getSuperclass();while (superClass != null) {
Field[] superFileds=superClass.getDeclaredFields();
allFields=ArrayUtils.addAll(allFields, superFileds);
superClass=superClass.getSuperclass();
}
这样就取到了类中的所有成员变量,包括基类的成员变量。
"父爱无声,但它一直都在。"