java反射获取类的所有成员变量(本类和基类)
我们知道在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(); }
这样就取到了类中的所有成员变量,包括基类的成员变量。
"父爱无声,但它一直都在。"
你要去做一个大人,不要回头,不要难过。