我們知道在Java的反射機制中,最核心的一個類就是Class類。
Class類中提供了兩個常用的獲取類的成員變量的方法。
方法1 getFields()
/** * Returns an array containing {@code Field} objects reflecting all * the accessible public fields of the class or interface represented by * this {@code Class} object. * * <p> If this {@code Class} object represents a class or interface with no * no accessible public fields, then this method returns an array of length * 0. * * <p> If this {@code Class} object represents a class, then this method * returns the public fields of the class and of all its superclasses. * * <p> If this {@code Class} object represents an interface, then this * method returns the fields of the interface and of all its * superinterfaces. * * <p> If this {@code Class} object represents an array type, a primitive * type, or void, then this method returns an array of length 0. * * <p> The elements in the returned array are not sorted and are not in any * particular order. * * @return the array of {@code Field} objects representing the * public fields * @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[] getFields() throws SecurityException { checkMemberAccess(Member.PUBLIC, Reflection.getCallerClass(), true); return copyFields(privateGetPublicFields(null)); }
從注釋上可以看出來,這個方法是用來獲取一個類和其所有父類中被public修飾符修飾的成員變量的。
方法2 getDeclaredFields()
/** * Returns an array of {@code Field} objects reflecting all the fields * declared by the class or interface represented by this * {@code Class} object. This includes public, protected, default * (package) access, and private fields, but excludes inherited fields. * * <p> If this {@code Class} object represents a class or interface with no * declared fields, then this method returns an array of length 0. * * <p> If this {@code Class} object represents an array type, a primitive * type, or void, then this method returns an array of length 0. * * <p> The elements in the returned array are not sorted and are not in any * particular order. * * @return the array of {@code Field} objects representing all the * declared fields of this class * @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 fields within this class * * <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[] getDeclaredFields() throws SecurityException { 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(); }
這樣就取到了類中的所有成員變量,包括基類的成員變量。
"父愛無聲,但它一直都在。"