Obtenga todos los campos privados usando la reflexión

4 minutos de lectura

avatar de usuario de user2152361
usuario2152361

Me pregunto si hay alguna manera de obtener todos los campos privados de alguna clase en Java y su tipo.

Por ejemplo, supongamos que tengo una clase:

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

Ahora me gustaría obtener todos los campos privados (aaa, bbb, ccc) de clase SomeClass (Sin saber el nombre de todos los campos por adelantado) y verifique su tipo.

  • @atk Nadie te obliga a responder; pero para muchos de nosotros que llegamos a esta pregunta de Google, la respuesta principal es una explicación mucho más sucinta que leer largas publicaciones sobre la reflexión. Incluso la cola larga de preguntas como esta contribuye a lo que SO es hoy.

    – Angad

    3 de septiembre de 2015 a las 8:07


  • Consulte ¿Cómo leo un campo privado en Java?

    – Martín Schröder

    25 de septiembre de 2015 a las 9:23

Avatar de usuario de Cyrille Ka
cirille ka

Es posible obtener todos los campos con el método getDeclaredFields() de Class. Luego, debe verificar el modificador de cada campo para encontrar los privados:

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

Tenga en cuenta que getDeclaredFields() no devolverá campos heredados.

Eventualmente, obtienes el tipo de los campos con el método Campo.getType().

  • Creo que el hecho de que esté trabajando contra una clase compilada lo hace bastante inconveniente porque los campos devueltos tienen nombres como m0, m1etc., y son del tipo java.lang.reflect.Method. ¿Esto podría deberse a que intento usar la reflexión en un Spring Bean lanzado a una interfaz?

    – Payne

    10 dic 2020 a las 19:41

Avatar de usuario de Kevin Bowersox
Kevin Bowersox

Puedes usar Modifier para determinar si un campo es privado. Asegúrese de usar el getDeclaredFields método para asegurarse de recuperar campos privados de la clase, llamando getFields solo devolverá los campos públicos.

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

  • @AfzaalAhmadZeeshan, ¿por qué cambió mi edición “clazz” a “clase”, cuando claramente necesitamos usar la variable “clazz” y no la palabra clave “clase”?

    – vallentín

    17 de noviembre de 2013 a las 19:05

  • Lo siento por ese error, pensé que era un error ya que no había ninguna variable asociada con el documento o el código en ninguna parte. Perdóname por eso..

    – Afzaal Ahmad Zeeshan

    17 de noviembre de 2013 a las 19:25

  • @AfzaalAhmadZeeshan había una variable, está en los argumentos del método. Sin embargo, ¿le importaría revocar su cambio, ya que no puedo cambiarlo?

    – vallentín

    18 de noviembre de 2013 a las 3:47


Probar FieldUtils de apache commons-lang3:

FieldUtils.getAllFieldsList(Class<?> cls)

Usando Java 8:

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

avatar de usuario de madx
madx

Comprobar si un campo es privado

Tú podrías filtrar los campos usando Modificador.isPrivate:

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

en un solo Field objeto que devuelve true si el campo es private


Recopilar todos los campos de una clase

A recoger todos los campos usar:

1) Si solo necesita los campos de la clase sin los campos tomados de la jerarquía de clases, simplemente puede usar:

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

2) Si no desea reinventar la rueda y obtener todos los campos de una jerarquía de clases en la que puede confiar Apache Commons Lang versión 3.2+ que proporciona 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));
    }
}

Avatar de usuario de Peter Lawrey
pedro laurey

¿Quieres decir como

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

¿Ha sido útil esta solución?