Listar todos los getters

Van un par de veces en que necesito imprimir todos los atributos de un objeto ( generalemente de otra persona ).

Les dejo este método de utiliería que itera todos los métodos de un objeto get se llamen "getXyz" e imprime el valor.

No es la técnica más depurada ( ni debería propagarse a producción ) pero por si a alguién le sirve ahista ( y para que la siguiente vez sepa a donde venir a buscarlo ).

Saludos

private static void debug( Object o ) {
    for( java.lang.reflect.Method m : o.getClass().getDeclaredMethods() ) {
        if( m.getName().startsWith("get") && m.getParameterTypes().length == 0  ) try {
                System.out.printf("%s = %s %n", m.getName() , m.invoke( o , new Object[]{}));
        } catch( Exception e ) {}
    }
}

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de ezamudio

dónde?

Dónde tienes que listar esos atributos? En una aplicación que está corriendo?

No es más fácil usar javap y grep?

javap -classpath mi:classpath:completo paquete.Clase |grep " get"

Ejemplo:

javap javax.crypto.Cipher |grep " get"

De un objeto vivo: class

De un objeto vivo:

class PersonaDTP {

        public String getName() {
                return "faba@bla.c";
        }
        public String getLastName() {
                return "Reyes";
        }
        public String getHora() {
                return "XYz y media";
        }

        public static void main( String ... args ) {
                PersonaDTP log = new PersonaDTP();
                Util.debug( log );
        }
}
$ java PersonaDTP
getLastName = Reyes
getHora = XYz y media
getName = faba@bla.c

Imagen de bferro

La reflexión es cara

La reflexión es caray no debe abusarse de ella. Si dispongo del código fuente prefiero abrir el archivo fuente y filtrarlo para obtener la firma de los getters. No veo muchos escenarios donde necesite eso.

Imagen de beto.bateria

jajaja, solo queria aportar

jajaja, solo queria aportar algo y ya lo desilusionaron, el proximo fin de semana se va a suicidar.

bueno como mejora podrias

bueno como mejora podrias obtener tambien los que inician con "is" (para los boolean)

Justo he tenido una intriga de clocar la clase y poner los atributos públicos y así complementar con mi entrada que habia puesto ( http://www.javamexico.org/blogs/javadabadoo/tostring ) que por cierto tu me indicabas justo lo que publicas ahora y después me recomendaste que a mi metodo toString le pasara el objeto y te decia que no por que los campos eran private... desde ahí comenzó mi curiosidad por hacer ese clon con métodos públicos y unir lo que había hecho con la idea que me habías recomendado... recuerdo haber visto hace tiempo un código que mediante reflexión te generaba una clase en tiempo de ejecución y le ponías el nombre a los atributos, los modificadores y obvio los valores... solo que no recuerdo exactamente donde

A lo que voy es (independientemente de lo conflictivo/costoso/poco viable) que creo que es siempre vigilar las propiedades directamente sin hacer lo que llamabas "instrumentación" pues los get o is no siempre significa que tengas una propiedad de ese nombre...

Calendar.getInstance() no tiene una propiedad llamada instance... un metodo isAlive() puede que haga una serie de acciones para retornarte un valor booleano sin tener la propiedad alive

@beto.bateria Ja ja ja claro

@beto.bateria Ja ja ja claro que no, está perfectamente justificado y jamás lo usaría en producción.

@bferro Yeap, es cara sobre todo cuando se usa a la ligera ( como en mi ejemplo ), pero es muy usada en prácticamente cualquier framework de Java ( básta con ver el stacktrace ) . Frameworks como Hibernate están prácticamente basados en ella, Groovy podría decirse que es puro reflection y así hay bastantes ejemplos.

Este ejemplo que puse lo usé nada menos hoy mismo para lo siguiente: Llevamos ya varios días de estar debuggeando una integración para saber que rayos me estaban mandando como argumentos ( más bien para saber qué no me estaban mandando ) y para varios beans que tienen entre 10 - 30 atributos ( no me pregunten porque, yo también lo odio ) Estar poniendo y quitando printlns ya me había vuelto loco y con esto logré ayudarles a mis contrapartes a saber que estaban haciendo mal.

En un mundo ideal ellos lo hubieran sabido, pero en ese mundo ideal no hubiera habido necesidad de debugguear tanto. Encontramos las fallas y quitamos el método así de fácil.

@jdd Si es verdad, en este caso en particular yo solo estaba interesado en los método publicos y el alcance es muy limitado.

Quizá al código que te refieres es un Dynamic Proxy.

Por cierto yo voy a necesitar algo como eso para hacer funcionar esto, pero para instrumentarlo en build time ( no en runtime ), ahi a ver si nos ponemos de acuerdo, pero todavía falta algun rato para eso.

@OscarRys, no se si esto

@OscarRys, no se si esto pueda funcionarte:

public class Reflection {

        public static void main(String[] args) throws Exception {
                Propiedades prop = new Propiedades();

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

                for (Field field : fields) {
                        field.setAccessible(true);
                        System.out.println(
                                        field.getType().getCanonicalName()
                                        + "\t" + field.getName()
                                        + "=" + field.get(prop));
                }

        }
}

class Propiedades {

        private String a, b, c, d, e, f;

        public Propiedades() {
                a = "AA";
                b = "BB";
                c = "CC";
                d = "DD";
                f = "FF";
        }
}

La saida es esta:

java.lang.String        a=AA
java.lang.String        b=BB
java.lang.String        c=CC
java.lang.String        d=DD
java.lang.String        e=null
java.lang.String        f=FF

En este codigo haces accesibles todos los campos privados y ahi si que puedes tener la certeza de que lo que listas son campos y no "lo que parecen ser campos"...

Me acuerdo que habia un codigo que te decia que te generaba clases en tiempo de ejecucion pero nunca lo encontre entnces mepuse a leer la docu de java.lang.reflect.Method y de java.lang.reflect.Field y note que en ambas clases exisitia un metodo setAccessible(boolean) y mira, resultó mas facil de lo que pensaba obtener los atributos privados de una clase... con estopodemos hacer que el metodo copy de la clase Method sea accesible y clonar los metodos de una clase y asi poder realizar una instrumentacion mas extensade las clases que Java nos "prohibe"... Lei un poco de instrumentacion y se oye genial eso, tengo una vaga idea de que se puede usar JMX pero la verdad no se bien de esas cosas

Como sea, se me ocurren hacer cosas con este nuevo hallazgo

¡Psst! Oye, Oscar...

 

¡Psst! Oye, Oscar... ¿Crees que el método reflectionToString de la clase org.apache.commons.lang.builder.ToStringBuilder hubiese sido útil? :-)

~~~