Java: obtenha todos os nomes de variáveis ​​em uma classe

91

Eu tenho uma classe e quero encontrar todos os seus campos públicos (não métodos). Como posso fazer isso?

Obrigado!

ufk
fonte
Você deve ser capaz de fazer isso usando a API do Reflection .
Crozin

Respostas:

134
Field[] fields = YourClassName.class.getFields();

retorna uma matriz de todas as variáveis ​​públicas da classe.

getFields()retornar os campos em toda a hereditariedade da classe. Se você deseja ter os campos definidos apenas na classe em questão, e não em suas superclasses, use getDeclaredFields()e filtre publicaqueles com a seguinte Modifierabordagem:

Modifier.isPublic(field.getModifiers());

O YourClassName.classliteral realmente representa um objeto do tipo java.lang.Class. Verifique seus documentos para métodos de reflexão mais interessantes.

A Fieldclasse acima é java.lang.reflect.Field. Você pode dar uma olhada no java.lang.reflectpacote completo .

Bozho
fonte
2
apenas uma nota - inicialmente minha resposta continha uma afirmação errada, mas foi votada a favor várias vezes. Leia com mais atenção;)
Bozho
1
@downvoter - o erro foi antes. Se você ver um agora, por favor, compartilhe.
Bozho
esta solução é lenta? ou podemos usá-lo livremente?
Dany Y
está certo. Mas não abuse.
Bozho
15

Você pode usar qualquer um dos dois de acordo com sua necessidade:

Field[] fields = ClassName.class.getFields(); // returns inherited members but not private members.
Field[] fields = ClassName.class.getDeclaredFields(); // returns all members including private members but not inherited members.

Para filtrar apenas os campos públicos da lista acima (com base no requisito), use o código abaixo:

List<Field> fieldList = Arrays.asList(fields).stream().filter(field -> Modifier.isPublic(field.getModifiers())).collect(
    Collectors.toList());
Sahil Chhabra
fonte
2

Conforme mencionado por poucos usuários, o código abaixo pode ajudar a encontrar todos os campos em uma determinada classe.

TestClass testObject= new TestClass().getClass();
Method[] methods = testObject.getMethods();
for (Method method:methods)
{
    String name=method.getName();
    if(name.startsWith("get"))
    {
        System.out.println(name.substring(3));
    }else if(name.startsWith("is"))
    {
        System.out.println(name.substring(2));
    }
}

No entanto, uma abordagem mais interessante está abaixo:

Com a ajuda da biblioteca Jackson, consegui encontrar todas as propriedades da classe do tipo String / inteiro / duplo e respectivos valores em uma classe Map. ( sem usar reflexões api! )

TestClass testObject = new TestClass();
com.fasterxml.jackson.databind.ObjectMapper m = new com.fasterxml.jackson.databind.ObjectMapper();

Map<String,Object> props = m.convertValue(testObject, Map.class);

for(Map.Entry<String, Object> entry : props.entrySet()){
    if(entry.getValue() instanceof String || entry.getValue() instanceof Integer || entry.getValue() instanceof Double){
        System.out.println(entry.getKey() + "-->" + entry.getValue());
    }
}
Amit Kaneria
fonte