Wann toString() überschreiben?

babuschka

Top Contributor
Hallo, also ich weiß, daß alle Klasse von der Klasse Object die Methode toString() erben und daß man in gewissen Situationen diese Methode an die jeweilige Klasse anpassen muss.


Was sind solche Situationen, wo man das muss? Ich habe mir mal ein Beispiel ausgedacht.

Wenn ich zum Beispiel eine neue Klasse "Katzen" schreibe, wie folgt:

Java:
class Katzen{

String name;
int age;

public Katzen(String name, int age){

  this.name= name;
  this.age = age;
}

public static void main( String[] args ){

 Katzen felix = new Katzen("Felix", 2);

System.out.println(felix);
}
}

So wird mir
Code:
Katzen@19821f
ausgegeben, okay.

Ist das Überschreiben jetzt so gemeint, daß ich in der Klasse "Katzen" die Methode
Java:
public String toString() {
  return name;
}

schreibe und dann statt Zeile 16 schreibe:

Java:
System.out.println(felix.toString() );
?

Oder habe ich die Funktionen bzw. den Sinn des Überschreibens missverstanden, denn man könnte ja auch einfach Zeile 16 ersetzen durch:

Java:
System.out.println(felix.name);

und wozu dann das Überschreiben und die Mühe, die Methode zu schreiben?
 

HimBromBeere

Top Contributor
Die MEthode toString() kannst du als Shortcut verwenden, also eine Art Standard-Methode. Wann immer also eine Ausgabe irgendwo machst, kannst du statt felix-toString() auch einfach felix schreiben...

In deinem Fall also:
Java:
System.out.println(felix);

EDIT: Mit toString() lieferst du laut JAVA-API eine String-Representation deiner Instanz zurück, also irgendetwas, was dem Objekt ´nen Namen gibt oder sonstwelche Informationen. So genau ist das nicht definiert, du kannst da auch "Katzenfutter" hinschreiben...
 
Zuletzt bearbeitet:
A

Andgalf

Gast
Na ja, so ein Object kann ja mehr als zwei properties haben.

Und wenn du jetzt von einer Katze, den Namen, das Alter, das Geschlecht, die Felllänge, die Farbe, die Größe und das Gewicht entsprechend ausgeben willst ... macht das Überschreiben der toString methode schon sinn.
 

babuschka

Top Contributor
Okay, wenn ich die Methode toString überschrieben habe, kann ich mir das .toString() also sparen.


Aber meine Frage war, ob ich den Sinn des Überschreibens richtig verstanden habe und wieso man sich die Mühe macht, wenn man auch felix.name nehmen kann,
 

babuschka

Top Contributor
Was ausprobieren?

Habe ich doch schon.

Wenn ich das mit dem Überschreiben weglasse und stattdessen

Code:
System.out.println(felix.name);

schreibe, wird der Name auch ausgegeben.


Daher ja meine Frage, wieso man das mit dem Überschreiben eigentlich macht...
 

Michael...

Top Contributor
Was sind solche Situationen, wo man das muss?
Die gibt es nicht ;-) Man muss die Methode nicht überschreiben.
Ist das Überschreiben jetzt so gemeint, daß ich in der Klasse "Katzen" die Methode
Java:
public String toString() {
  return name;
}
Ja
denn man könnte ja auch einfach Zeile 16 ersetzen durch:

Java:
System.out.println(felix.name);
Das wäre besser. Noch besser wäre allerdings, wenn man nur über getter und setter auf die Variable zugreifen kann, es also eine Methode getName() gibt, die den Namen zurück gibt.
und wozu dann das Überschreiben und die Mühe, die Methode zu schreiben?
Man kann die Methode überschreiben, um z.B. den Zustand eines Objektes zurück zugeben (Debugging, Logging...)
Java:
public String toString() {
    return this.getClass().getName() + "(Name: " + name + ", Age: " + age + ")";
}
Ein Fall bei dem man das Überschreiben der Methode "missbrauchen" kann ist, im Zusammenhang mit GUI Komponenten (JList, JTable, JTree...) diese verwenden standardmäßig ebenfalls die toString(), um das Objekt darzustellen. Hiermit erspart man sich das programmieren eines Renderers.
 

faetzminator

Gesperrter Benutzer
Es gibt Situationen, in denen man ein [c]toString()[/c] nicht einfach mit einem [c]System.out.println(felix.name);[/c] ersetzen kann. Du könntest für deine Katze(n) folgende Methode schreiben:
Java:
public String toString() {
    return name + ", " age + (age == 1 ? " Jahr" : " Jahre");
Was dann bei
Java:
List<Katze> katzen = ...;
for (Katze katze : katzen) {
    System.out.println(katze);
}
sowas ausgeben würde
Code:
Friedolin, 2 Jahre
Schnurri, 1 Jahr
Hanswurst, 3 Jahre
 

Harry05

Bekanntes Mitglied
Ist es gut ein Automatismus für die toString zu entwickeln, so dass man die toString() immer per rat hat als Clean code ? So das man die toString immer mit der Anpassung der Klasse mit anpasst?
 

LimDul

Top Contributor
Schwer zu sagen. Es erhöht den Wartungsaufwand, wenn du immer die toString Methode anpassen musst, wenn du deine Klasse änderst. Und wenn du die Objekte nie ausgibst, dann ist der Nutzen minimal, aber der Aufwand erhöht. Und wenn man es nicht konsequent pflegt und mit Tests absichert, ist wenn du es mal brauchst, dann garantiert die Methode toString() nicht mehr synchron zur Klasse.

Ich hab mir für ein privates Projekt was per Reflection gebastelt:
Java:
public class GenericToString {

	private static final Logger logger = LoggerFactory.getLogger(GenericToString.class);

	public static String toString(Object o) {
		String result = o.getClass().getSimpleName() + " [";
		Field[] fields = o.getClass().getDeclaredFields();
		return result + Arrays.stream(fields).map(f -> mapField(o, f)).collect(Collectors.joining(", ")) + "]";
	}

	private static String mapField(Object o, Field f) {
		String valueString = getFieldValue(o, f);
		return f.getName() + "=\"" + valueString + "\"";
	}

	private static String getFieldValue(Object o, Field f) {
		try {
			f.setAccessible(true);
			Object value = f.get(o);
			if (value == null) {
				return null;
			} else {
				return value.toString();
			}
		} catch (IllegalArgumentException | IllegalAccessException e) {
			logger.warn("Error while accessing field " + f, e);
			return null;
		}
	}

Dann kann ich toString() einfach so überschreiben:
Java:
	@Override
	public String toString() {
		return GenericToString.toString(this);
	}

Ob man das aber wieder will, ist auch eine Sache - damit gebe ich den kompletten Objektzustand nach außen über die toString Methode. Das ist je nach Anforderung auch nicht gewünscht.

Von daher ist meine Meinung, es gibt keine einfache Antwort auf die Frage.
 
K

kneitzel

Gast
Ich hab mir für ein privates Projekt was per Reflection gebastelt:

Also ich würde da nicht zu Reflection greifen sondern mir den Code eher von der IDE generieren lassen (Dann muss man ihn aber bei Änderungen anpassen - aber man kann ihn jederzeit anpassen) oder die Generierung beim Compile-Lauf durchführen lassen (Project Lombok).

Ich persönlich greife immer sehr gerne zu Lombok.
 

Harry05

Bekanntes Mitglied
@LimDul ja gut, aber Putzt du als Hausmeister oder wer das mach, nicht den Treppenflur, nur weil du den Fußabtreter immer zu Seite packen musst? Es muss zur Firmen Kultur(Clean Code Vereinbarung> gehören ,dass immer die toString anzupassen mit jeder Klasse Änderung und außerdem so wie @JustNobody sagt Generieren IDE's schon eine toString(). Also ich glaube das ist ein Aufwand von nicht mal 2min sogar noch weniger, was nach hinten wider aufgefangen wird.
 

httpdigest

Top Contributor
Es erstaunt mich, dass das hier noch nicht erwähnt wurde (EDIT: ups, habe gerade den Satz von @JustNobody überlesen... sorry!) , aber hierfür gibt es https://projectlombok.org/. Einfach als Standard für jedes Projektsetup einführen (ist bei uns so) und du hast keine Probleme mehr mit korrekten toString(), hashCode(), equals(), gettern, settern, constructoren, builder-Klassen, ... nichts muss manuell geschrieben/maintained oder "semi-manuell" per IDE generiert werden.
Ein ähnliches Ziel verfolgt auch: https://openjdk.java.net/jeps/359
 
K

kneitzel

Gast
Also das Problem ist aus meiner Sicht, dass bei manueller Anpassung (Und wenn es nur ein klick in der IDE ist, da etwas zu generieren) es früher oder später zu Fehlern kommen wird. So menschliche Fehler sind schlicht unnötig und daher ist es aus meiner Sicht relativ fatal, hier auf den reinen Faktor Mensch zu setzen.

Daher ist da aus meiner Sicht Lombok mit die beste Wahl.

Aber generell frage ich mich doch, was hier der toString Methode für eine Bedeutung beigemessen wurde. Wo wird denn toString wirklich benutzt in komplexen Klassen? Wenn ich da jetzt etwas zurück denke, dann ist das eigentlich nur eine Sache für Logfiles....
Denn sobald man eine Applikation schreibt, dann wird man doch das Model von der View trennen. Dabei ist es jetzt egal, wie man das nun genau auftrennt und wie man die Teile beschimpft: MVC, MVVM, ... Eine sinnvolle Aufteilung wird hoffentlich erfolgen...
 
K

kneitzel

Gast
Wo hier gerade Lombok so positiv betrachtet wird möchte ich aber auch Kritik anbringen:

Das ganze Projekt ist nicht per se gut und sollte als Ganzes eingesetzt werden!

Es gibt Teile, die ich sehr positiv sehe:
@Getter, @Setter, @Data, @Builder, @EqualsHashCode, @ToString

Es gibt Teile, die ich neutral sehe:
@Log-Variationen z.B. - Ob ein @Slf4j an einer Klasse besser ist als eine Zeile private static final Logger log = .... muss jeder für dich beantworten ...

Es gibt Teile, die komplett ablehne und deren Einsatz in meinen Augen nicht zu rechtfertigen ist:
@Cleanup ist hier das beste Beispiel. Mit Java 8 gibt es das try with resources und damit für so ein Feature keine Rechtfertigung mehr!

Viele Dinge habe ich noch nicht genannt. Jeder kann sich da seine eigenen Gedanken machen. Aber ich würde generell immer erst schauen, ob es nicht andere Lösungen gibt....

Und wenn Lösungen kommen, dann sollte man sich diese auch sehr gut ansehen - @httpdigest hat z.B. auf die Records hingewiesen. Hier muss jeder für sich entscheiden, ob sowas nicht ein Ersatz für bisherige @Data Einsätze sein kann und was hier evtl. bei der eigenen Art und Weise angepasst werden sollte. Das Stichwort immutable ist hier wichtig und interessant und evtl. ist man da ja auch an anderer Stelle drüber gestolpert wie z.B. bei (parallel) Streams, wo dies wichtig sein könnte um Laufzeitprobleme zu verhindern ... Aber das führt jetzt zu weit in ein anderes Thema, das ich hier jetzt nicht weiter vertiefen möchte.
 

LimDul

Top Contributor
@LimDul ja gut, aber Putzt du als Hausmeister oder wer das mach, nicht den Treppenflur, nur weil du den Fußabtreter immer zu Seite packen musst? Es muss zur Firmen Kultur(Clean Code Vereinbarung> gehören ,dass immer die toString anzupassen mit jeder Klasse Änderung und außerdem so wie @JustNobody sagt Generieren IDE's schon eine toString(). Also ich glaube das ist ein Aufwand von nicht mal 2min sogar noch weniger, was nach hinten wider aufgefangen wird.
Klar. Von der reinen Lehre hast du Recht.

Aber ich hab mittlerweile genug Erfahrung um zu wissen:
* Fehler passieren.
* Bei Dingen, wo der Nutzen schwerer vermittelbar ist (was bei einer toString Mehode der Fall ist, wenn aufgrund der Anwendung das quasi nie relevant ist, weil nie Objekte mittels toString ausgegeben werden) denken die Leute automatisch weniger dran, bzw. es fällt eher runter.

Da kann man Prinzipien wie Clean Code & Co noch so hoch halten und sich noch so sehr als Team drauf einschwören es nicht zu vergessen - es wird passieren. Und es fällt garantiert erst dann auf, wenn man es dann auf einmal doch braucht.

Anders sieht es aus, wenn die toString Methode regelmäßig genutzt und gebraucht wird - dann ist es deutlich einfacher dran zu denken und es fühlt sich für Entwickler weniger wie eine lästige Pflicht an.

Für mich ist wichtig: Clean Code macht man nicht, weil irgendwer anders das für eine gute Idee hält und hält sich dann sklavisch an alles, sondern Clean Code & Co macht man, weil man den Sinn einsieht und versteht, was es einem bringt. Und wenn bestimmte Teilaspekte für das konkrete Projekt mehr Aufwand als Nutzen bringen, dann lässt man es und zwingt es nicht sklavisch drüber. (Nichtsdestotrotz sollte man gute Gründe haben, von bewährten Prinzipien abzuweichen - ein einfaches "Ich hab keinen Bock drauf, ich find das doof" reicht nicht).

Daher stimme ich JustNobody zu - sowas wie Lombok ist da im Zweifelsfall die bessere Wahl (Das hatte ich nicht auf dem Schirm, obwohl mal für ein Projekt erst mal rausfinden musste, wie ich das in Eclipse einbinde)
 
K

kneitzel

Gast
* Bei Dingen, wo der Nutzen schwerer vermittelbar ist (was bei einer toString Mehode der Fall ist, wenn aufgrund der Anwendung das quasi nie relevant ist, weil nie Objekte mittels toString ausgegeben werden) denken die Leute automatisch weniger dran, bzw. es fällt eher runter.

Anders sieht es aus, wenn die toString Methode regelmäßig genutzt und gebraucht wird - dann ist es deutlich einfacher dran zu denken und es fühlt sich für Entwickler weniger wie eine lästige Pflicht an.

Wenn die toString Methode nicht gebraucht wird: warum wird diese dann geschrieben? Und wie rechtfertigt Ihr dies im Bereich Clean Code? Wenn die Anforderung nicht da ist, dann macht es da durchaus Sinn, die auch einfach weg zu lassen. Und dann KISS beachten - warum etwas komplizieren, wenn es ganz trivial geht: @ToString mit einem import reicht ja schon :)

Daher stimme ich JustNobody zu - sowas wie Lombok ist da im Zweifelsfall die bessere Wahl (Das hatte ich nicht auf dem Schirm, obwohl mal für ein Projekt erst mal rausfinden musste, wie ich das in Eclipse einbinde)

Das ist relativ trivial. Es gibt ein Addon, welches einfach über die lobok jar Aufgerufen werden kann. Lombok ist da ehh sehr schön. Wenn man das verwendet und die Verwendung gefällt einem nicht, dann kann man die generierte Version der Source Datei nehmen. Auf Wunsch wandelt lombok einem auch alle Files direkt um.

Das ist etwas, das mir sehr gut gefällt, denn wenn ich morgen kein lombok mehr nutzen will, dann ist es eine Sache von wenigen Minuten es komplett aus dem Projekt zu entfernen.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
KogoroMori21 Wann ist der richtige Zeitpunkt, um sich Hilfe zu suchen? (Bin Informatik-Student) Java Basics - Anfänger-Themen 10
I Logik Zahlungsprozess - Wann Bestellobjekt anlegen? Java Basics - Anfänger-Themen 2
C Java Array Struktur, welche ist wann besser? Java Basics - Anfänger-Themen 12
berserkerdq2 Java streams, wann nutze ich ::, also 2x Doppelpuntk bei Streams? Java Basics - Anfänger-Themen 5
W Wann und warum hashcode und equals? Java Basics - Anfänger-Themen 14
W Wann Rückgabewerte 0, 1, -1? Java Basics - Anfänger-Themen 27
berserkerdq2 Wann soll ich den Stream schließen, wenn ich das in einer Methode habe? Java Basics - Anfänger-Themen 8
K In andere Zahlensysteme umwandeln, wann klappt immer der Trick mit log? Java Basics - Anfänger-Themen 6
W Zur Vererbung: Wann und wie? Java Basics - Anfänger-Themen 35
F Wann ist es eine Instanz und wann nicht? Java Basics - Anfänger-Themen 1
C Instanzen, wann muss ich Instanzen erzeugen & wo?) Java Basics - Anfänger-Themen 23
S Wann Methode abstract? Java Basics - Anfänger-Themen 10
S Wann buffer löschen? Java Basics - Anfänger-Themen 5
R Wie überprüfen wann der User online oder offline ist? Java Basics - Anfänger-Themen 5
C Polymorphie Was genau ist Polymorphie und wann genau sollte man es verwenden? Java Basics - Anfänger-Themen 9
I Wann ist Client plattformunabhängig? Java Basics - Anfänger-Themen 22
M Best Practice Wann eine Methode schreiben ? Java Basics - Anfänger-Themen 14
K Warum funktioniert das und wann erden die Objektmethoden nun ausgeführt? Java Basics - Anfänger-Themen 7
IngoF Welches Event kommt wann? Java Basics - Anfänger-Themen 8
M Wann eigene implementierte HashCode Methode zwingend erforderlich? Java Basics - Anfänger-Themen 1
X Wann schreibt man diese Syntax zeichen { } Java Basics - Anfänger-Themen 8
O Wann nutzt man static? Java Basics - Anfänger-Themen 19
C Klassendesign / Wann Interface implementieren und wann Klassen vererben? Java Basics - Anfänger-Themen 3
S Wann existiert eine Instanz (eigene Klasse) Java Basics - Anfänger-Themen 8
M Wann PATH und wann JAVA_HOME in Windows System 7 setzen? Java Basics - Anfänger-Themen 2
M Wann final verwenden? Java Basics - Anfänger-Themen 5
M Wann eine Wrapper Klasse verwenden und wann einen primitiven Datentypen? Java Basics - Anfänger-Themen 8
D Ab wann getter und setter Java Basics - Anfänger-Themen 2
B Erkennen, wann static oder nicht? Java Basics - Anfänger-Themen 7
E wann welche Konstanten verwenden? Java Basics - Anfänger-Themen 7
P Wann Byte-Stream und wann Character-Stream? Java Basics - Anfänger-Themen 11
T Vererbung Wann wird die Methode paint aufgerufen? Java Basics - Anfänger-Themen 4
M Wann statische Methoden/Attribute? Java Basics - Anfänger-Themen 2
vandread Java Wildcards - Wann super wann extends? Java Basics - Anfänger-Themen 2
K Wann Vererbung und wann Interface verwenden? Java Basics - Anfänger-Themen 12
D Wann genau nutze ich ein solches Interface? Java Basics - Anfänger-Themen 3
K Wann genau brauche ich die Anweisung gleich null? Java Basics - Anfänger-Themen 10
S OOP Wann Proxies und Interfaces? Java Basics - Anfänger-Themen 3
P Threads Wann läuft es parallel ab ? Java Basics - Anfänger-Themen 4
C Variablen Wann werden Instanzvariablen initalisiert? Java Basics - Anfänger-Themen 10
P Java Stream, wann welche Stream verwenden? Java Basics - Anfänger-Themen 3
T Ab wann ist es ein großes Projekt? Java Basics - Anfänger-Themen 35
N Bessere Performance durch final: wann denn überhaupt? Java Basics - Anfänger-Themen 28
D Wann genau abstrakte Klasse und wann ein Interface verwenden? Java Basics - Anfänger-Themen 4
W Wann nutze ich "import"? Java Basics - Anfänger-Themen 12
A junit test wann verwendet man "was"? Java Basics - Anfänger-Themen 4
H Wann ein Objekt der Programmklasse in main anlegen Java Basics - Anfänger-Themen 2
G Wann ist ein == Vergleich bei Gleitkommazahlen fahrlässig? Java Basics - Anfänger-Themen 8
T Wann for und wann while?? Java Basics - Anfänger-Themen 35
-horn- Wann wird alles NaN erzeugt? Java Basics - Anfänger-Themen 22
S Wann wird eine Klasse geladen? Java Basics - Anfänger-Themen 17
C this - wann verwende ich das? Java Basics - Anfänger-Themen 10
T Threads - Ab wann wirds Kritisch?! Java Basics - Anfänger-Themen 7
M Wann muss man eine Variable mit set-/get-Methoden in eine Bean schreiben? Java Basics - Anfänger-Themen 19
G field public/private wann Java Basics - Anfänger-Themen 11
GambaJo Ab wann neue Klasse erzeugen? Java Basics - Anfänger-Themen 2
G Wann Arrays, wann Collections? Java Basics - Anfänger-Themen 36
GambaJo Wann try.catch nutzen? Java Basics - Anfänger-Themen 11
B objekt wann als final deklarieren? Java Basics - Anfänger-Themen 2
N Wann muss eine Methode - protected sein wann public wann. Java Basics - Anfänger-Themen 5
Y Wann / Wozu inner class Java Basics - Anfänger-Themen 3
K StringBuilder notwendig ab wann? Java Basics - Anfänger-Themen 42
S wann static Funktionen wann nicht Java Basics - Anfänger-Themen 6
N Wann und wie oft finalize Methode verwenden( überschreiben ) Java Basics - Anfänger-Themen 6
Bernasconi Programmierstil / Wann eine neue Datei? Java Basics - Anfänger-Themen 5
M wann, welche schleife Java Basics - Anfänger-Themen 3
M Ab wann ist die Datei sichtbar? Java Basics - Anfänger-Themen 3
G Herausfinden, wann mehrere Threads abgeschlossen sind Java Basics - Anfänger-Themen 3
G Überprüfen wann ein Dokument abläuft? Java Basics - Anfänger-Themen 3
N SAX, StAX, JDOM oder DOM , ab wann welches für XML Java Basics - Anfänger-Themen 14
M Wann ist ein Programm beendet? Java Basics - Anfänger-Themen 6
G Wann am besten getSize() aufrufen? Java Basics - Anfänger-Themen 6
I Festellen wann Methode in anderer Klasse fertig ist Java Basics - Anfänger-Themen 5
M wann statische klassen? Java Basics - Anfänger-Themen 14
M Wann ist initialisieren sinnvoll? Java Basics - Anfänger-Themen 4
B Wann Comparator und wann Comparable Java Basics - Anfänger-Themen 6
R Wann benutzt man << oder >> ? Java Basics - Anfänger-Themen 2
G Klassen: Wann initialisiere ich wo meine Variabeln Java Basics - Anfänger-Themen 6
W LocalDate toString und nach Split falsch "erkannt"? Java Basics - Anfänger-Themen 8
W ArrayList und toString Java Basics - Anfänger-Themen 17
W toString bei composition Java Basics - Anfänger-Themen 4
M Unterschied Integer.toString(x) und x.toString() Java Basics - Anfänger-Themen 22
E Einrücken inner der toString()-Methode Java Basics - Anfänger-Themen 34
W Objekte über Scanner Input; ToString Probleme... Java Basics - Anfänger-Themen 4
M Polymorphie toString Java Basics - Anfänger-Themen 13
Y Wie kann ich ein Element in einer toString finden. Java Basics - Anfänger-Themen 2
A Implementierung von String toString methode() Java Basics - Anfänger-Themen 4
P falscher booleanwert bei toString Java Basics - Anfänger-Themen 4
P Methode die eigentlich einen Scanner benötigt mit toString() Java Basics - Anfänger-Themen 5
M Wie analysiert JSON eine toString-Ausgabe ? Java Basics - Anfänger-Themen 1
J Methoden toString()-Date Formatter Java Basics - Anfänger-Themen 8
V Neue Ausgabe von toString nach Methodenaufruf Java Basics - Anfänger-Themen 9
M Die Inhalte eines Arrays mit der Methode Arrays.toString ausgeben Java Basics - Anfänger-Themen 4
H toString-Methode Java Basics - Anfänger-Themen 24
E Vererbung mit toString() Java Basics - Anfänger-Themen 6
O Referenz - toString Java Basics - Anfänger-Themen 9
B toString mit optionaler Ausgabe überrschreiben Java Basics - Anfänger-Themen 5
J toString-Methode in Verbindung mit varArgs-Konstruktor Java Basics - Anfänger-Themen 18
C Methoden toString Java Basics - Anfänger-Themen 4
B toString() Dilemma Java Basics - Anfänger-Themen 7

Ähnliche Java Themen

Neue Themen


Oben