Java: obtenga todos los nombres de variables en una clase

91

Tengo una clase y quiero encontrar todos sus campos públicos (no métodos). ¿Cómo puedo hacer esto?

¡Gracias!

ufk
fuente
Debería poder hacer esto usando Reflection API .
Crozin

Respuestas:

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

devuelve una matriz de todas las variables públicas de la clase.

getFields()devuelve los campos en toda la jerarquía de clases. Si desea tener los campos definidos solo en la clase en cuestión, y no en sus superclases, use getDeclaredFields()y filtre los publicque tienen el siguiente Modifierenfoque:

Modifier.isPublic(field.getModifiers());

El YourClassName.classliteral realmente representa un objeto de tipo java.lang.Class. Consulte sus documentos para conocer métodos de reflexión más interesantes.

La Fieldclase anterior es java.lang.reflect.Field. Puede echar un vistazo al java.lang.reflectpaquete completo .

Bozho
fuente
2
solo una nota: inicialmente mi respuesta contenía una declaración incorrecta, sin embargo, fue votada a favor varias veces. Lea con más atención;)
Bozho
1
@downvoter: el error fue antes. Si ves uno ahora, compártelo.
Bozho
¿Esta solución es lenta? ¿O podemos usarlo libremente?
Dany Y
está bien. Pero no lo uses en exceso.
Bozho
15

Puede utilizar cualquiera de los dos según sus necesidades:

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 solo los campos públicos de la lista anterior (según el requisito), use el siguiente código:

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

Como lo mencionaron algunos usuarios, el siguiente código puede ayudar a encontrar todos los campos en una clase determinada.

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));
    }
}

Sin embargo, a continuación se muestra un enfoque más interesante:

Con la ayuda de la biblioteca de Jackson, pude encontrar todas las propiedades de clase de tipo String / integer / double y los valores respectivos en una clase Map. (¡ sin usar reflections 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
fuente