Comment remplacer correctement toString () en Java?

87

Cela semble un peu stupide, mais j'ai besoin d'aide sur ma toString()méthode et c'est très irritant. J'ai essayé de chercher en ligne parce que toStringc'est celui où il se trompe et "ne trouve pas le constructeur Kid # 2" même s'il est là et je ferais même autre chose et cela ne fonctionne pas. Ok c'était beaucoup alors voici mon 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 Donc mon toString ci-dessus (je sais, mon troisième paramètre est désactivé, devrait être une chaîne) est désactivé. Si je code en dur une valeur pour la troisième chose, il se détraque et dit qu'il ne peut pas le trouver (ci-dessus). Alors, comment puis-je obtenir la date et la rompre?

La classe appelant ceci est ci-dessous

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  

J'ai essayé de rechercher plusieurs constructeurs et cela n'a vraiment pas aidé. J'ai essayé de rechercher des toString()méthodes et d'utiliser la toString()logique des méthodes précédentes que j'avais créée auparavant, mais c'est tout nouveau, donc cela n'a jamais fonctionné.

Aidez-moi?

user1283885
la source
5
Veuillez poster le code qui compilerait réellement. Votre toString()méthode ne renvoie pas de chaîne et vous ne pouvez pas appeler un constructeur comme celui-ci. Ce que vous essayez même d'accomplir n'est pas clair. Veuillez lire tinyurl.com/so-hints et clarifier votre question.
Jon Skeet
Le ToStringCreator de Spring ( github.com/SpringSource/spring-framework/tree/master/… ) fait très bien le travail.
Ritesh
Pour info, les anciennes classes de date-heure terriblement gênantes telles que java.util.Date, java.util.GregorianCalendaret java.text.SimpleDateFormatsont maintenant héritées , supplantées par les classes java.time intégrées à Java 8 et versions ultérieures. Voir le didacticiel d'Oracle .
Basil Bourque

Réponses:

134

Le toStringest censé renvoyer un fichier String.

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

Je vous suggère d'utiliser les fonctionnalités de votre IDE pour générer la toStringméthode. Ne le codez pas à la main.

Par exemple, Eclipse peut le faire si vous faites simplement un clic droit sur le code source et sélectionnez Source > Generate toString

Adarshr
la source
1
Ce n'est pas une bonne pratique, car vous utilisez la concaténation de chaînes.
Amit le
1
StringBuilder est un meilleur choix dans une telle situation.
Amit le
9
@Amit Le compilateur Java utilise StringBuilderimplicitement. Il n'y a pas de problème à moins que vous ne l'utilisiez en boucle.
chrylis -cautouslyoptimistic-
Dans Netbeans; il est sous Source -> Insert Code...puis sélectionneztoString
Fer
10

Méthode Java toString ()

Si vous souhaitez représenter un objet sous forme de chaîne, la méthode toString () entre en vigueur.

La méthode toString () renvoie la représentation sous forme de chaîne de l'objet.

Si vous imprimez un objet, le compilateur java appelle en interne la méthode toString () sur l'objet. Donc, redéfinir la méthode toString (), retourne la sortie souhaitée, cela peut être l'état d'un objet etc. dépend de votre implémentation.

Avantage de la méthode Java toString ()

En remplaçant la méthode toString () de la classe Object, nous pouvons renvoyer les valeurs de l'objet, nous n'avons donc pas besoin d'écrire beaucoup de code.

Sortie sans méthode toString ()

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

Vous pouvez voir dans l'exemple n ° 1 ci-dessus. l'impression de s1 et s2 imprime les valeurs Hashcode des objets mais je souhaite imprimer les valeurs de ces objets. Puisque le compilateur java appelle en interne la méthode toString (), la substitution de cette méthode renverra les valeurs spécifiées. Comprenons-le avec l'exemple ci-dessous:

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

Notez que toString () est principalement lié au concept de polymorphisme en Java. Dans Eclipse, essayez de cliquer sur toString () et faites un clic droit dessus, puis cliquez sur Open Declaration et voyez d'où vient la Superclass toString ().

Linux Le
la source
4

Vous pouvez créer un nouvel objet dans le toString (). utilisation

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

au lieu de

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

Vous pouvez modifier la chaîne de retour si nécessaire. Il existe d'autres moyens de stocker la date à la place du calendrier.

sudmong
la source
3

Vous ne pouvez pas appeler un constructeur comme s'il s'agissait d'une méthode normale, vous ne pouvez l'appeler qu'avec newpour créer un nouvel objet:

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

Mais construire un nouvel objet à partir de votre méthode toString () n'est pas ce que vous voulez faire.

Adrian Pronk
la source
3

Comme d'autres l'ont expliqué, ce toStringn'est pas l'endroit pour instancier votre classe. Au lieu de cela, la toStringméthode est destinée à créer une chaîne représentant la valeur d'une instance de votre classe, en rapportant au moins les champs de données les plus importants stockés dans cet objet. Dans la plupart des cas, toStringest utilisé pour le débogage et la journalisation, pas pour votre logique métier.

Pour générer du texte représentant la valeur d'un objet à afficher à un utilisateur, ajoutez une autre méthode. Les gens nomment souvent la méthode quelque chose comme getDisplayName. Par exemple, DayOfWeek::getDisplayNameet Month::getDisplayName.

StringJoiner

À partir de Java 8 et versions ultérieures, la manière la plus moderne d'implémenter toStringconsiste à utiliser la StringJoinerclasse. Comme le dit le doc:

StringJoiner est utilisé pour construire une séquence de caractères séparés par un délimiteur et éventuellement commençant par un préfixe fourni et se terminant par un suffixe fourni.

Utilisez comme ceci:

@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.
}

Personne [nom = Alice | téléphone = 555.867.5309]

Basil Bourque
la source
1
c'est plus élégant
esQmo_
2

Le code suivant est un exemple. Question basée sur la même chose, au lieu d'utiliser la conversion basée sur l'IDE, existe-t-il un moyen plus rapide de mettre en œuvre afin qu'à l'avenir les changements se produisent, nous n'ayons pas besoin de modifier les valeurs encore et encore?

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

Si vous êtes intéressé par les tests unitaires, vous pouvez déclarer un "ToStringTemplate" public, puis vous pouvez tester votre toString. Même si vous ne le testez pas unitaire, je pense qu'il est "plus propre" et utilise 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());
    } 
}

Vous pouvez maintenant effectuer un test unitaire en créant le Kid, en définissant les propriétés et en effectuant votre propre string.format sur le ToStringTemplate et en comparant.

rendre ToStringTemplate statique-final signifie "UNE VERSION" de la vérité, plutôt que d'avoir une "copie" du modèle dans le test unitaire.

grenadeCoder
la source
1

En fait, vous devrez retourner quelque chose comme ça car toString doit renvoyer une chaîne

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

et vous faites quelque chose de mal dans le constructeur, vous définissez la variable définie par l'utilisateur sur le nom alors que vous devez faire le contraire. Ce que tu ne devrais pas faire

n = this.name

Ce que tu devrais faire

this.name = n

Espère que cela aide merci

Mohamed Sherif Noureldin
la source
1

nous pouvons même écrire comme ça en créant un nouvel objet String dans la classe et en lui attribuant ce que nous voulons dans le constructeur et le renvoyer dans la méthode toString qui est surchargée

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
la source
1

Ayez toujours un moyen facile: clic droit > Générer > toString () > sélectionnez le modèle que vous voulez. entrez la description de l'image ici

logbasex
la source
0

Le meilleur moyen à mon avis est d'utiliser la bibliothèque google gson:

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

ou apache commons lang façon de réflexion

utilisateur666
la source
0
  1. si vous utilisez le bloc-notes: alors

    public String toString(){
    
     return ""; ---now here you can use variables which you have created for your class
    
    }
    
  2. si vous utilisez eclipse IDE, appuyez sur

    -alt +shift +s 
    

    -cliquez sur la méthode de substitution toString ici, vous obtiendrez des options pour sélectionner le type de variables que vous souhaitez sélectionner.

Le mec
la source
0

Une manière agréable et concise est d'utiliser les annotations Lombok. Il a une @ToStringannotation, qui générera une implémentation de la toString()méthode. Par défaut, il affichera le nom de votre classe, avec chaque champ, dans l'ordre, séparés par des virgules. Vous pouvez facilement personnaliser votre sortie en passant des paramètres à l'annotation, par exemple:

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

Ce qui est équivalent à Java pur:

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

Si vous utilisez uniquement toString()pour le débogage d'un DTO , vous pouvez générer automatiquement une sortie lisible par l'homme avec quelque chose comme ce qui suit:

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

Cependant, cela n'est pas approprié pour les déploiements de production si le DTO peut contenir des informations personnelles (qui ne doivent pas être capturées dans les journaux).

Brent Bradburn
la source