BlogKontaktTagcloud

Generisches toString in Java mit Reflection

Mit Reflection unter Java kann man viele lustige Dinge anstellen. Versteht zwar keiner, macht aber nichts! Wer's nicht versteht muss es lernen.

Mein heutiges Resultat ist eine generische toString-Methode die sowohl den Klassennahmen als auch alle über Getter ereichbaren Werte ausgibt. Sehr praktisch für Debug-Output.

public String toString(){
Class c = this.getClass();
StringBuffer buf = new StringBuffer(c.getName()+ ":\n");

Method m[] = c.getDeclaredMethods();
for (Method method : m) {
if(method.getName().startsWith("get") && method.getParameterTypes().length == 0){
try {
buf.append("- "+method.getName().substring(3)+": "+method.invoke(this, (Object[])null) +"\n");
} catch (Exception e) {}
}
}

return buf.toString();
}
Ähnliche Beiträge:
Generische Decorator in Java mit Reflection
Named parameters in Java (bgl-style)
SCJP, now!
Generics Gala
Variable Parameterlisten in Java
Comments (10)  Permalink

comments

leu @ 23.05.2006 23:22 CEST
ich verstehs nicht.
Bertrand Delacrétaz @ 24.05.2006 12:01 CEST
Hmm...among my teams, anyone who writes

catch (Exception e) {}

is an instant candidate for tarring and feathering [1] ;-)

Apart from that, this is cool!

[1] http://en.wikipedia.org/wiki/Tar_and_feather
leo @ 24.05.2006 12:59 CEST
@Herr Leu: Als nicht Informatik müssen Sie's nicht zwangsläufig verstehen.

@Bertrand: First of all I think I won't work in the same teams as you! ;-) Very radical methodes! But your right I should write a comment.
Thomas Marti @ 24.05.2006 15:53 CEST
Hallo Leo

Dein Codeschnippsel hat mich zu einer eigenen Version inspiriert... ;)

Natürlich schön gekapselt in einer separaten Klasse:

--------------------------------------------------------
package ch.integis.jpoxspatial.util;
import java.lang.ref.WeakReference;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class ToStringHelper {
private static final String NEW_LINE = System.getProperty( "line.separator", "n" );
private final WeakReference ref;
public ToStringHelper( Object o ) {
ref = new WeakReference( o );
}

public String toString(){
Class c = ref.get().getClass();
StringBuilder buf = new StringBuilder( c.getName() + ":" + NEW_LINE );

for ( Method method : c.getDeclaredMethods() ) {
if ( method.getName().startsWith( "get" ) && method.getParameterTypes().length == 0 && Modifier.isPublic( method.getModifiers() ) ){
try {
buf.append( "- " + method.getName().substring( 3 ) + ": " + method.invoke( ref.get(), (Object[])null ) + NEW_LINE );
} catch ( Exception e ) {}
}
}
return buf.toString();
}

public static String toString( Object o ) {
return ( new ToStringHelper( o ) ).toString();
}
}
--------------------------------------------------------


Bin zwar nicht ganz sicher, ob's die WeakReference braucht...
leo @ 24.05.2006 18:20 CEST
WeakReference ist wohl keine all zu gute Idee. Wenn du ein ToStringHelper-Objekt anlegst und erst später toString aufrufst könnte es so sein das dein übergebenes Objekt abgeräumt wird bevor du es benützt, was dann sicher zu unschönen Fehlern führen würde.
Thomas Marti @ 24.05.2006 18:45 CEST
Hmm...dann halt einfach:

private final Object o;
leo @ 24.05.2006 23:51 CEST
Ja das sieht besser aus.
javaSux @ 02.10.2006 11:36 CEST
funzt nicht mit abgeleiteten Klassen da c.getDeclaredMethods() nur die Methoden aus der Klasse findet und nicht _alle_ des Objektes...
javaSux @ 02.10.2006 11:54 CEST
damit das auch mit Vererbung tut muss man die Methode c.getMethods() benutzen
whoopsie @ 19.07.2009 11:54 CEST
Hier eine Variante, welche auf der obigen basiert, aber die Super-Klassen innerhalb der "eigenen" Package-Struktur berücksichtigt...

public String toString(){
Class<?> c = this.getClass();
StringBuffer buf = new StringBuffer(c.getName() + "n");
do {
Method m[] = c.getDeclaredMethods();
for (Method method : m) {
if(method.getName().startsWith("get") && method.getParameterTypes().length == 0){
try {
buf.append(c.getSimpleName() + " -> " + method.getName().substring(3) + ": " + method.invoke(this, (Object[])null) +"n");
} catch (Exception e) {}
}
}
c = c.getSuperclass();
} while (this.getClass().getPackage().getName()
.startsWith(c.getPackage().getName()));
return buf.toString();
}


Gruß,
Manfred

add a comment

The Trackback URL to this comment is:
http://leo.freeflux.net/blog/plugin=trackback(1155).xml

Keine (weiteren) neuen Kommentare erlaubt.