Java反射getFields方法和getDeclaredFields方法的区别

最近在写注解相关代码的时候经常会使用到反射机制,关于Class类的两个方法getFieldsgetDeclaredFields有一些疑惑,这两个方法到底哪里不一样,有什么区别呢。最好的教程就是源码,直接进入源码可以看到如下注释:

/**
     * Returns an array containing {@code Field} objects reflecting all
     * the accessible public fields of the class or interface represented by
     * this {@code Class} object.
     *
     * 

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. * *

If this {@code Class} object represents a class, then this method * returns the public fields of the class and of all its superclasses. * *

If this {@code Class} object represents an interface, then this * method returns the fields of the interface and of all its * superinterfaces. * *

If this {@code Class} 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. * * @return the array of {@code Field} objects representing the * public fields * @throws SecurityException * 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 {@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)); }

/**
     * 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.
     *
     * 

If this {@code Class} object represents a class or interface with no * declared fields, then this method returns an array of length 0. * *

If this {@code Class} 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. * * @return the array of {@code Field} objects representing all the * declared fields of this class * @throws SecurityException * 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 * {@link SecurityManager#checkPermission * s.checkPermission} method with * {@code RuntimePermission("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 {@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[] getDeclaredFields() throws SecurityException { checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true); return copyFields(privateGetDeclaredFields(false)); }

以上注释的意思大概就是说:

  • getFields方法只会返回public修饰符修饰的属性,且能返回父类属性
  • getDeclaredFields方法会返回当前类的所有声明属性,包括publicprivateprotecteddefaultstatic修饰符修饰的属性,但是不能返回父类的属性。

下面,以一个例子说明,更加简洁易懂:

/**
 * 父类
 */
public class OldStrudent {
    private String oldName;
    public boolean oldSex;
}
/**
 * 子类
 */
public class Student extends OldStrudent {
    private String name;
    private Integer score;
    private boolean sex;
    public String teacher;
    private static String id;
}
/**
 * 测试类
 */
import java.lang.reflect.Field;

public class Main {

    public static void main(String[] args) {
        Field[] fields = Student.class.getFields();
        for (Field field : fields) {
            System.out.println(field.getName());
        }

        System.out.println("---------");
        Field[] decFields = Student.class.getDeclaredFields();
        for (Field field : decFields) {
            System.out.println(field.getName());
        }
    }
}
/**
 * 输出结果:
 * teacher
 * oldSex
 * ---------
 * name
 * score
 * sex
 * teacher
 * id
 */

同理,ClassgetMethodgetDeclaredMethods方法也是这个逻辑。

你可能感兴趣的:(Java反射getFields方法和getDeclaredFields方法的区别)