Java反射获取所有私有字段


76

我想知道是否有一种方法可以获取java中某个类的所有私有字段及其类型。

例如,假设我有一堂课

class SomeClass {
    private String aaa;
    private SomeOtherClass bbb;
    private double ccc;
}

现在,我想获得的所有私有字段(aaabbbccc类)SomeClass(如果不知道所有领域前期的名称),并检查它们的类型。


7
@atk没有人强迫您回答;但是对于我们许多从Google着手解决这个问题的人来说,最重要的答案是比透彻阅读长篇文章的反思更为简洁。甚至像这样的长尾问题也对当今的SO有所贡献。
Angad 2015年

Answers:


123

有可能获得与方法的所有字段getDeclaredFields()Class。然后,您必须检查每个字段的修饰符以查找私有字段:

List<Field> privateFields = new ArrayList<>();
Field[] allFields = SomeClass.class.getDeclaredFields();
for (Field field : allFields) {
    if (Modifier.isPrivate(field.getModifiers())) {
        privateFields.add(field);
    }
}

请注意,getDeclaredFields()这不会返回继承的字段。

最终,您可以使用Field.getType()方法获得字段的类型。


13

您可以Modifier用来确定字段是否为私有。确保使用该getDeclaredFields方法来确保您从类中检索私有字段,调用getFields只会返回公共字段。

public class SomeClass {

    private String aaa;
    private Date date;
    private double ccc;
    public int notPrivate;

    public static void main(String[] args) {
        List<Field> fields = getPrivateFields(SomeClass.class);
        for(Field field: fields){
            System.out.println(field.getName());
        }
    }

    public static List<Field> getPrivateFields(Class<?> theClass){
        List<Field> privateFields = new ArrayList<Field>();

        Field[] fields = theClass.getDeclaredFields();

        for(Field field:fields){
            if(Modifier.isPrivate(field.getModifiers())){
                privateFields.add(field);
            }
        }
        return privateFields;
    }
}

2
@AfzaalAhmadZeeshan当我们显然需要使用变量“ clazz”而不是关键字“ class”时,为什么将我的编辑“ clazz”更改为“ class”
vallentin

我为这个错误感到抱歉,我认为这是一个错误,因为在任何地方都没有与文档或代码相关联的变量!为此,请原谅我..
阿夫扎尔·艾哈迈德·泽山

3
@AfzaalAhmadZeeshan有一个变量,它在方法的参数中。不过,由于我无法更改,您是否愿意撤消更改。
vallentin


8

使用Java 8:

Field[] fields = String.class.getDeclaredFields();
List<Field> privateFieldList = Arrays.asList(fields).stream().filter(field -> Modifier.isPrivate(field.getModifiers())).collect(
        Collectors.toList());

7

检查字段是否私有

您可以使用Modifier.isPrivate过滤字段

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
// ...
Field field = null;
// retrieve the field in some way
// ...
Modifier.isPrivate(field.getModifiers())

在单个Field对象上,true如果该字段是private


收集课程的所有字段

收集所有字段,请使用:

1)如果只需要类的字段,而无需从类层次结构中获取字段,则可以简单地使用:

Field[] fields = SomeClass.class.getDeclaredFields();

2)如果您不想重新发明轮子并获得类层次结构的所有字段,则可以依赖Apache Commons Lang 3.2+版本,该版本提供FieldUtils.getAllFieldsList

import java.lang.reflect.Field;
import java.util.AbstractCollection;
import java.util.AbstractList;
import java.util.AbstractSequentialList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

import org.apache.commons.lang3.reflect.FieldUtils;
import org.junit.Assert;
import org.junit.Test;

public class FieldUtilsTest {

    @Test
    public void testGetAllFieldsList() {

        // Get all fields in this class and all of its parents
        final List<Field> allFields = FieldUtils.getAllFieldsList(LinkedList.class);

        // Get the fields form each individual class in the type's hierarchy
        final List<Field> allFieldsClass = Arrays.asList(LinkedList.class.getFields());
        final List<Field> allFieldsParent = Arrays.asList(AbstractSequentialList.class.getFields());
        final List<Field> allFieldsParentsParent = Arrays.asList(AbstractList.class.getFields());
        final List<Field> allFieldsParentsParentsParent = Arrays.asList(AbstractCollection.class.getFields());

        // Test that `getAllFieldsList` did truly get all of the fields of the the class and all its parents 
        Assert.assertTrue(allFields.containsAll(allFieldsClass));
        Assert.assertTrue(allFields.containsAll(allFieldsParent));
        Assert.assertTrue(allFields.containsAll(allFieldsParentsParent));
        Assert.assertTrue(allFields.containsAll(allFieldsParentsParentsParent));
    }
}

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.