JavaでtoString()を正しくオーバーライドする方法は?


87

少しばかげtoString()ているように聞こえますが、私の方法について助けが必要であり、それは非常に苛立たしいものです。オンラインで調べてみたのtoStringは、それが台無しになっていて、「Kidコンストラクター#2が見つからない」のですが、そこにあり、他のことをしても機能しません。わかりました、それはたくさんだったので、ここに私のコードがあります:

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 

さて、上記のtoString(3番目のパラメーターはオフです。文字列である必要があります)はオフです。3番目の値をハードコーディングすると、問題が発生し、これが見つからないと表示されます(上記)。では、どうすれば日付を取得して分割できますか?

これを呼び出すクラスは以下のとおりです

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  

複数のコンストラクターを調べてみましたが、実際には役に立ちませんでした。toString()メソッドを調べて、以前toString()に作成した以前のメソッドロジックを使用してみましたが、これはまったく新しいため、機能しませんでした。

助けて?


5
実際にコンパイルされるコードを投稿してください。あなたのtoString()メソッドは、文字列を返さない、とあなたはそのようなコンストラクタを呼び出すことはできません。あなたが何を達成しようとしているのかさえはっきりしていません。tinyurl.com/so-hintsを読んで、質問を明確にしてください。
Jon Skeet 2012年

SpringのToStringCreator(github.com/SpringSource/spring-framework/tree/master/…)は非常にうまく機能します。
リテッシュ2012年

FYI、ひどく面倒な古い日付時刻クラスのようなjava.util.Datejava.util.GregorianCalendarそしてjava.text.SimpleDateFormat今のレガシーに取って代わられ、java.timeのJavaの8に、後に内蔵されたクラス。Oracleによるチュートリアル参照してください。
バジルバーク

回答:


134

toString返すことになっていますString

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

IDEの機能を利用してtoStringメソッドを生成することをお勧めします。手作業でコーディングしないでください。

たとえば、Eclipseは、ソースコードを右クリックして、 Source > Generate toString


1
文字列の連結を使用しているため、これは適切な方法ではありません。
2016

1
このような状況では、StringBuilderの方が適しています。
アミット

9
@AmitJavaコンパイラはStringBuilder暗黙的に使用します。ループで使用しない限り問題ありません。
chrylis -cautiouslyoptimistic- 2017

Netbeansでは; それは下にありSource -> Insert Code...、選択されますtoString
Fer

10

Java toString()メソッド

オブジェクトを文字列として表現したい場合は、toString()メソッドが存在します。

toString()メソッドは、オブジェクトの文字列表現を返します。

オブジェクトを出力すると、Javaコンパイラはそのオブジェクトに対して内部的にtoString()メソッドを呼び出します。したがって、toString()メソッドをオーバーライドすると、目的の出力が返されます。オブジェクトの状態などは、実装によって異なります。

Java toString()メソッドの利点

ObjectクラスのtoString()メソッドをオーバーライドすることで、オブジェクトの値を返すことができるため、多くのコードを記述する必要はありません。

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

上記の例#1で見ることができます。s1とs2を出力すると、オブジェクトのハッシュコード値が出力されますが、これらのオブジェクトの値を出力したいと思います。Javaコンパイラは内部でtoString()メソッドを呼び出すため、このメソッドをオーバーライドすると、指定された値が返されます。以下の例でそれを理解しましょう:

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

toString()は、主にJavaのポリモーフィズムの概念に関連していることに注意してください。Eclipseで、toString()をクリックして右クリックし、Open Declarationをクリックして、スーパークラスtoString()の出所を確認します。


4

toString()で新しいオブジェクトを作成できます。使用する

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

の代わりに

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

必要に応じて、戻り文字列を変更できます。カレンダーの代わりに日付を保存する他の方法があります。


3

通常のメソッドであるかのようにコンストラクターを呼び出すことはできません。コンストラクターを呼び出すことができるのはnew、新しいオブジェクトを作成するためだけです。

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

しかし、toString()メソッドから新しいオブジェクトを作成することは、あなたがやりたいことではありません。


3

他の人が説明したように、それtoStringはあなたのクラスをインスタンス化する場所ではありません。代わりに、このtoStringメソッドは、クラスのインスタンスの値を表す文字列を作成し、少なくともそのオブジェクトに格納されているデータの最も重要なフィールドについてレポートすることを目的としています。ほとんどの場合、toStringは、ビジネスロジックではなく、デバッグとロギングに使用されます。

ユーザーに表示するオブジェクトの値を表すテキストを生成するには、別のメソッドを追加します。人々はしばしばメソッドをのような名前を付けgetDisplayNameます。たとえば、DayOfWeek::getDisplayNameおよびMonth::getDisplayName

StringJoiner

Java 8以降では、実装toStringする最も新しい方法はStringJoinerクラスを使用することです。ドキュメントが言うように:

StringJoinerは、区切り文字で区切られ、オプションで指定されたプレフィックスで始まり、指定されたサフィックスで終わる文字のシーケンスを構築するために使用されます。

このように使用します:

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

人[名前=アリス| 電話= 555.867.5309]


1
それは、よりエレガントだ
esQmo_

2

次のコードはサンプルです。IDEベースの変換を使用する代わりに、同じものに基づく質問は、将来変更が発生したときに値を何度も変更する必要がないように実装するより速い方法がありますか?

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

2

ユニットテストに興味がある場合は、パブリック「ToStringTemplate」を宣言してから、toStringをユニットテストできます。ユニットテストをしなくても、「よりクリーン」で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());
    } 
}

これで、Kidを作成し、プロパティを設定し、ToStringTemplateで独自のstring.formatを実行して比較することにより、単体テストを行うことができます。

ToStringTemplateをstatic-finalにするということは、単体テストでテンプレートの「コピー」を作成するのではなく、真実の「1つのバージョン」を意味します。


1

toStringは文字列を返す必要があるため、実際には次のようなものを返す必要があります

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

コンストラクターで実際に何か間違ったことをした場合、ユーザーが設定した変数を名前に設定しますが、その逆を行う必要があります。してはいけないこと

n = this.name

あなたがすべきこと

this.name = n

これが感謝に役立つことを願っています


1

クラスに新しいStringオブジェクトを作成し、コンストラクターで必要なものを割り当てて、オーバーライドされたtoStringメソッドに返すことで、このように記述することもできます。

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()  
 }  
}

1

常に簡単な方法があります:右クリック>生成> toString() >必要なテンプレートを選択します。 ここに画像の説明を入力してください


0

私の意見では、グーグルgsonライブラリを使用するのが最善の方法です。

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

またはApacheCommons lang Reflection Way


0
  1. メモ帳を使用している場合:その後

    public String toString(){
    
     return ""; ---now here you can use variables which you have created for your class
    
    }
    
  2. Eclipse IDEを使用している場合は、

    -alt +shift +s 
    

    -ここでoverridetoStringメソッドをクリックすると、選択する変数のタイプを選択するためのオプションが表示されます。


0

素晴らしく簡潔な方法は、Lombokアノテーションを使用することです。それは持っている@ToStringの実装が生成されます注釈、toString()方法を。デフォルトでは、クラス名が各フィールドとともに、コンマで区切られて順番に出力されます。パラメータをアノテーションに渡すことで、出力を簡単にカスタマイズできます。例:

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

これは純粋なJavaと同等です。

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

0

DTOのtoString()デバッグに使用しているだけの場合は、次のように人間が読める形式の出力を自動的に生成できます。

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

ただし、DTOにPIIが含まれている可能性がある場合(ログに記録しないでください)、これは実稼働展開には適していません。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.