Wie kann man toString () in Java richtig überschreiben?

86

Klingt ein bisschen dumm, aber ich brauche Hilfe bei meiner toString()Methode und es ist sehr ärgerlich. Ich habe versucht, online nachzuschlagen, weil es das toStringist, wo es vermasselt wird und "Kid Konstruktor # 2 nicht findet", obwohl es da ist und ich sogar etwas anderes machen würde und es nicht funktioniert. Ok, das war viel, also hier ist mein Code:

import java.util.*; 
   class Kid {  
      String name; 
      double height; 
      GregorianCalendar bDay; 

      public Kid () { 
         this.name = "HEAD";
         this.height = 1; 
         this.bDay = new GregorianCalendar(1111,1,1); 
      } 

      public Kid (String n, double h, String date) {
      // method that toString() can't find somehow
         StringTokenizer st = new StringTokenizer(date, "/", true);
         n = this.name;
         h = this.height;
      } 

      public String toString() { 
         return Kid(this.name, this.height, this.bDay);
      } 
   } //end class 

Ok Also mein toString oben (ich weiß, mein dritter Parameter ist aus, sollte ein String sein) ist aus. Wenn ich einen Wert für die dritte Sache fest codiere, geht er durcheinander und sagt, dass er diesen nicht finden kann (oben). Wie kann ich das Datum ermitteln und auflösen?

Die Klasse, die dies nennt, ist unten

class Driver {   
   public static void main (String[] args) {   
      Kid kid1 = new Kid("Lexie", 2.6, "11/5/2009");   
      System.out.println(kid1.toString());
   } //end main method 
} //end class  

Ich habe versucht, mehrere Konstruktoren zu erforschen, und es hat wirklich nicht geholfen. Ich habe versucht, toString()Methoden zu erforschen , und habe versucht, frühere zu verwendentoString() Methodenlogik zu verwenden, aber dies ist brandneu, sodass es nie funktioniert hat.

Hilfe?

user1283885
quelle
5
Bitte geben Sie die Postleitzahl ein, die tatsächlich kompiliert werden würde. Ihre toString()Methode gibt keinen String zurück und Sie können einen solchen Konstruktor nicht aufrufen. Es ist unklar, was Sie überhaupt erreichen wollen. Bitte lesen Sie tinyurl.com/so-hints und klären Sie Ihre Frage.
Jon Skeet
Der ToStringCreator des Frühlings ( github.com/SpringSource/spring-framework/tree/master/… ) macht den Job sehr gut.
Ritesh
Zu Ihrer Information, die furchtbar lästig alten Datum Zeitklassen wie java.util.Date, java.util.GregorianCalendarund java.text.SimpleDateFormatsind jetzt Erbe , durch die verdrängten java.time Klassen in Java gebaut 8 und höher. Siehe Tutorial von Oracle .
Basil Bourque

Antworten:

134

Der toStringsoll a zurückgeben String.

public String toString() { 
    return "Name: '" + this.name + "', Height: '" + this.height + "', Birthday: '" + this.bDay + "'";
} 

Ich schlage vor, Sie nutzen die Funktionen Ihrer IDE, um die zu generieren toString Methode . Codieren Sie es nicht von Hand.

Eclipse kann dies beispielsweise tun, wenn Sie einfach mit der rechten Maustaste auf den Quellcode klicken und auswählen Source > Generate toString

adarshr
quelle
1
Dies ist keine gute Vorgehensweise, da Sie die Verkettung von Zeichenfolgen verwenden.
Amit
1
StringBuilder ist in einer solchen Situation die bessere Wahl.
Amit
8
@Amit Der Java-Compiler verwendet StringBuilderimplizit. Es gibt kein Problem, wenn Sie es nicht in einer Schleife verwenden.
Chrylis
In Netbeans; es ist unter Source -> Insert Code...dann auswählentoString
Fer
10

Java toString () -Methode

Wenn Sie ein Objekt als Zeichenfolge darstellen möchten, wird die Methode toString () verwendet.

Die Methode toString () gibt die Zeichenfolgendarstellung des Objekts zurück.

Wenn Sie ein Objekt drucken, ruft der Java-Compiler intern die toString () -Methode für das Objekt auf. Wenn Sie also die toString () -Methode überschreiben, die gewünschte Ausgabe zurückgeben, kann dies der Status eines Objekts usw. sein. Dies hängt von Ihrer Implementierung ab.

Vorteil der Java toString () -Methode

Durch Überschreiben der toString () -Methode der Object-Klasse können wir Werte des Objekts zurückgeben, sodass wir nicht viel Code schreiben müssen.

Ausgabe ohne toString () -Methode

class Student{  
 int id;  
 String name;  
 String address;  

 Student(int id, String name, String address){  
 this.id=id;  
 this.name=name;  
 this.address=address;  
 }  

 public static void main(String args[]){  
   Student s1=new Student(100,”Joe”,”success”);  
   Student s2=new Student(50,”Jeff”,”fail”);  

   System.out.println(s1);//compiler writes here s1.toString()  
   System.out.println(s2);//compiler writes here s2.toString()  
 }  
}  

Output:Student@2kaa9dc
       Student@4bbc148

Sie können im obigen Beispiel Nr. 1 sehen. Beim Drucken von s1 und s2 werden die Hashcode-Werte der Objekte gedruckt, aber ich möchte die Werte dieser Objekte drucken. Da der Java-Compiler die toString () -Methode intern aufruft, werden beim Überschreiben dieser Methode die angegebenen Werte zurückgegeben. Lassen Sie es uns anhand des folgenden Beispiels verstehen:

Example#2

Output with overriding toString() method

class Student{  
 int id;  
 String name;  
 String address;  

 Student(int id, String name, String address){  
 this.id=id;  
 this.name=name;  
 this.address=address;  
 }  

//overriding the toString() method  
public String toString(){ 
  return id+" "+name+" "+address;  
 }  
 public static void main(String args[]){  
   Student s1=new Student(100,”Joe”,”success”);  
   Student s2=new Student(50,”Jeff”,”fail”);  

   System.out.println(s1);//compiler writes here s1.toString()  
   System.out.println(s2);//compiler writes here s2.toString()  
 }  
} 

Output:100 Joe success
       50 Jeff fail

Beachten Sie, dass toString () hauptsächlich mit dem Konzept des Polymorphismus in Java zusammenhängt. Versuchen Sie in Eclipse, auf toString () zu klicken und mit der rechten Maustaste darauf zu klicken. Klicken Sie dann auf Open Declaration (Deklaration öffnen) und sehen Sie, woher die Superklasse toString () stammt.

Linux Le
quelle
4

Sie können ein neues Objekt in toString () erstellen. verwenden

return "Name = " + this.name +" height= " + this.height;

anstatt

return Kid(this.name, this.height, this.bDay);

Sie können die Rückgabezeichenfolge nach Bedarf ändern. Es gibt andere Möglichkeiten, das Datum anstelle des Kalanders zu speichern.

Sudmong
quelle
3

Sie können einen Konstruktor nicht so aufrufen, als wäre es eine normale Methode. Sie können ihn nur aufrufen new, um ein neues Objekt zu erstellen:

Kid newKid = new Kid(this.name, this.height, this.bDay);

Das Erstellen eines neuen Objekts aus Ihrer toString () -Methode ist jedoch nicht das, was Sie tun möchten.

Adrian Pronk
quelle
3

Wie andere erklärten, toStringist dies nicht der richtige Ort, um Ihre Klasse zu instanziieren. Stattdessen soll die toStringMethode eine Zeichenfolge erstellen, die den Wert einer Instanz Ihrer Klasse darstellt und über mindestens die wichtigsten in diesem Objekt gespeicherten Datenfelder berichtet. In den meisten Fällen,toString wird es zum Debuggen und Protokollieren verwendet, nicht für Ihre Geschäftslogik.

Fügen Sie eine andere Methode hinzu, um Text zu generieren, der den Wert eines Objekts darstellt, das einem Benutzer angezeigt werden soll. Die Leute nennen die Methode oft so etwas wie getDisplayName. Zum Beispiel DayOfWeek::getDisplayNameund Month::getDisplayName.

StringJoiner

Ab Java 8 und höher toStringwürde die StringJoinerKlasse die modernste Art der Implementierung verwenden . Wie der Arzt sagt:

StringJoiner wird verwendet, um eine durch ein Trennzeichen getrennte Zeichenfolge zu erstellen, die optional mit einem angegebenen Präfix beginnt und mit einem angegebenen Suffix endet.

Verwenden Sie wie folgt:

@Override
public String toString ()
{
    return new StringJoiner(                           // In Java 8 and later, StringJoiner is used to construct a sequence of characters separated by a delimiter and optionally starting with a supplied prefix and ending with a supplied suffix.
                " | " ,                                // Delimiter
                Person.class.getSimpleName() + "[ " ,  // Prefix
                " ]"                                   // Suffix
            )
            .add( "name=" + name )                     // Append
            .add( "phone=" + phone )                   // Append
            .toString();                               // Convert entire sequence to a single `String` object.
}

Person [Name = Alice | Telefon = 555.867.5309]

Basil Bourque
quelle
1
das ist eleganter
esQmo_
2

Der folgende Code ist ein Beispiel. Gibt es eine schnellere Möglichkeit, eine IDE-basierte Konvertierung zu implementieren, damit die Änderungen in Zukunft nicht mehr immer wieder geändert werden müssen?

@Override
    public String toString() {
        return "ContractDTO{" +
                "contractId='" + contractId + '\'' +
                ", contractTemplateId='" + contractTemplateId + '\'' +
                '}';
    }
RCR
quelle
2

Wenn Sie an Unit-Tests interessiert sind, können Sie eine öffentliche "ToStringTemplate" deklarieren und anschließend Ihren toString einem Unit-Test unterziehen. Auch wenn Sie es nicht Unit-testen, denke ich, es ist "sauberer" und verwendet String.format.

public class Kid {

    public static final String ToStringTemplate = "KidName='%1s', Height='%2s', GregCalendar='%3s'";

    private String kidName;
    private double height;
    private GregorianCalendar gregCalendar;

    public String getKidName() {
        return kidName;
    }

    public void setKidName(String kidName) {
        this.kidName = kidName;
    }

    public double getHeight() {
        return height;
    }

    public void setHeight(double height) {
        this.height = height;
    }

    public GregorianCalendar getGregCalendar() {
        return gregCalendar;
    }

    public void setGregCalendar(GregorianCalendar gregCalendar) {
        this.gregCalendar = gregCalendar;
    }

    public String toString() { 
        return String.format(ToStringTemplate, this.getKidName(), this.getHeight(), this.getGregCalendar());
    } 
}

Jetzt können Sie Unit-Tests durchführen, indem Sie das Kid erstellen, die Eigenschaften festlegen und Ihr eigenes string.format in der ToStringTemplate ausführen und vergleichen.

ToStringTemplate statisch-final zu machen bedeutet "EINE VERSION" der Wahrheit, anstatt eine "Kopie" der Vorlage im Unit-Test zu haben.

granadaCoder
quelle
1

Nun, eigentlich müssen Sie so etwas zurückgeben, weil toString einen String zurückgeben muss

public String toString() {
 return "Name :" + this.name + "whatever :" + this.whatever + "";
}

und wenn Sie im Konstruktor tatsächlich etwas falsch machen, setzen Sie die vom Benutzer festgelegte Variable auf den Namen, während Sie das Gegenteil tun müssen. Was du nicht tun solltest

n = this.name

Was du machen solltest

this.name = n

Hoffe das hilft danke

Mohamed Sherif Noureldin
quelle
1

Wir können sogar so schreiben, indem wir ein neues String-Objekt in der Klasse erstellen und es im Konstruktor zuweisen, was immer wir wollen, und dieses in der überschriebenen toString-Methode zurückgeben

public class Student{  
 int id;  
 String name;  
 String address;  
 String details;
 Student(int id, String name, String address){  
 this.id=id;  
 this.name=name;  
 this.address=address;  
 this.details=id+"  "+name+"  "+address;  
 }  

//overriding the toString() method  
public String toString(){ 
  return details;  
 }  
 public static void main(String args[]){  
   Student s1=new Student(100,"Joe","success");  
   Student s2=new Student(50,"Jeff","fail");  

   System.out.println(s1);//compiler writes here s1.toString()  
   System.out.println(s2);//compiler writes here s2.toString()  
 }  
}
user7321815
quelle
0

Der beste Weg ist meiner Meinung nach die Verwendung der Google Gson-Bibliothek:

        @Override
public String toString() {
    return new GsonBuilder().setPrettyPrinting().create().toJson(this);
}

oder Apache Commons Lang Reflection Way

user666
quelle
0
  1. Wenn Sie den Editor verwenden: dann

    public String toString(){
    
     return ""; ---now here you can use variables which you have created for your class
    
    }
  2. Wenn Sie die Eclipse-IDE verwenden, drücken Sie

    -alt +shift +s 

    -Klicken Sie hier auf die Methode zum Überschreiben der Zeichenfolge. Sie erhalten Optionen, um auszuwählen, welche Art von Variablen Sie auswählen möchten.

Der Kerl
quelle
0

Eine gute und prägnante Möglichkeit ist die Verwendung von Lombok-Anmerkungen. Es verfügt über eine @ToStringAnmerkung, die eine Implementierung der toString()Methode generiert . Standardmäßig wird Ihr Klassenname zusammen mit jedem Feld in der durch Kommas getrennten Reihenfolge gedruckt. Sie können Ihre Ausgabe einfach anpassen, indem Sie Parameter an Annotation übergeben, z.

@ToString(of = {"name", "lastName"})

Welches ist das Äquivalent von reinem Java:

public String toString() {
        return "Person(name=" + this.name + ", lastName=" + this.experienceInYears + ")";
    }
Stinger
quelle
0

Wenn Sie nur toString()ein DTO zum Debuggen verwenden , können Sie automatisch eine lesbare Ausgabe mit folgenden Funktionen generieren :

import com.fasterxml.jackson.databind.ObjectMapper;
...
public String toString() {
    try { return new ObjectMapper().writeValueAsString(this); }
    catch (Exception e) { return "{ObjectMapper failed}"; }
}

Dies ist jedoch nicht für Produktionsbereitstellungen geeignet, wenn das DTO möglicherweise PII enthält (die nicht in Protokollen erfasst werden sollten).

Brent Bradburn
quelle
0

Immer einen einfachen Weg: Klicken Sie mit der rechten Maustaste auf > Generieren > toString () > wählen Sie die gewünschte Vorlage aus. Geben Sie hier die Bildbeschreibung ein

logbasex
quelle