Bagaimana cara menimpa toString () dengan benar di Java?

88

Kedengarannya agak bodoh, tapi saya butuh bantuan dalam toString()metode saya dan itu sangat menjengkelkan. Saya mencoba mencari secara online karena itu toStringadalah salah satu yang mengacaukan dan "tidak menemukan Konstruktor anak # 2" meskipun itu ada di sana dan saya bahkan akan melakukan sesuatu yang lain dan tidak berhasil. Ok itu banyak, jadi inilah kode saya:

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 Jadi toString saya di atas (saya tahu, parameter ketiga saya tidak aktif, seharusnya String) tidak aktif. Jika saya melakukan hardcode nilai untuk hal ketiga, itu menjadi rusak dan mengatakan tidak dapat menemukan ini (di atas). Jadi bagaimana saya bisa mendapatkan tanggal dan memecahnya?

Kelas memanggil ini di bawah

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  

Saya mencoba meneliti beberapa konstruktor dan itu benar-benar tidak membantu. Saya mencoba toString()metode penelitian , dan mencoba menggunakan toString()logika metode sebelumnya yang saya buat sebelumnya tetapi ini baru sehingga tidak pernah berhasil.

Tolong?

pengguna1283885
sumber
5
Silakan posting kode yang sebenarnya akan dikompilasi. Anda toString()metode tidak kembali string, dan Anda tidak dapat memanggil konstruktor seperti itu. Tidak jelas apa yang Anda coba capai. Harap baca tinyurl.com/so-hints dan klarifikasi pertanyaan Anda.
Jon Skeet
ToStringCreator Musim Semi ( github.com/SpringSource/spring-framework/tree/master/… ) melakukan pekerjaan dengan sangat baik.
Ritesh
FYI, kelas tanggal-waktu lama yang sangat merepotkan seperti java.util.Date, java.util.GregorianCalendardan java.text.SimpleDateFormatsekarang sudah lama , digantikan oleh kelas java.time yang dibangun ke dalam Java 8 dan yang lebih baru. Lihat Tutorial oleh Oracle .
Basil Bourque

Jawaban:

136

Itu toStringseharusnya mengembalikan String.

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

Saya sarankan Anda menggunakan fitur IDE Anda untuk menghasilkan toStringmetode ini. Jangan membuat kode sendiri.

Misalnya, Eclipse dapat melakukannya jika Anda cukup mengklik kanan pada kode sumber dan memilih Source > Generate toString

adarshr
sumber
1
Ini bukan praktik yang baik, karena Anda menggunakan penggabungan string.
Amit
1
StringBuilder adalah pilihan yang lebih baik dalam situasi seperti ini.
Amit
9
@Amit Kompilator Java menggunakan StringBuildersecara implisit. Tidak ada masalah kecuali Anda menggunakannya dalam satu lingkaran.
chrylis -cautiouslyoptimistic-
Di Netbeans; itu di bawah Source -> Insert Code...lalu pilihtoString
Fer
11

Java toString () metode

Jika Anda ingin merepresentasikan objek apa pun sebagai string, metode toString () akan ada.

Metode toString () mengembalikan representasi string dari objek.

Jika Anda mencetak objek apa pun, compiler java secara internal memanggil metode toString () pada objek tersebut. Jadi menimpa metode toString (), mengembalikan keluaran yang diinginkan, dapat berupa status objek, dll. Bergantung pada implementasi Anda.

Keuntungan dari metode Java toString ()

Dengan menimpa metode toString () dari kelas Object, kita bisa mengembalikan nilai dari objek, jadi kita tidak perlu menulis banyak kode.

Output tanpa metode 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

Anda dapat melihat pada contoh # 1 di atas. mencetak s1 dan s2 mencetak nilai kode hash dari objek tetapi saya ingin mencetak nilai dari objek ini. Karena compiler java secara internal memanggil metode toString (), mengganti metode ini akan mengembalikan nilai yang ditentukan. Mari kita pahami dengan contoh yang diberikan di bawah ini:

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

Perhatikan bahwa toString () sebagian besar terkait dengan konsep polimorfisme di Jawa. Di Eclipse, coba klik toString () dan klik kanan padanya, lalu klik Open Declaration dan lihat dari mana Superclass toString () berasal.

Linux Le
sumber
4

Anda bisa membuat objek baru di toString (). menggunakan

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

dari pada

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

Anda dapat mengubah string kembali sesuai kebutuhan. Ada cara lain untuk menyimpan tanggal sebagai pengganti kalender.

sudmong
sumber
3

Anda tidak dapat memanggil konstruktor seolah-olah itu adalah metode normal, Anda hanya dapat memanggilnya dengan newuntuk membuat objek baru:

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

Tetapi membuat objek baru dari metode toString () bukanlah hal yang ingin Anda lakukan.

Adrian Pronk
sumber
3

Seperti yang dijelaskan orang lain, toStringini bukanlah tempat untuk membuat instance kelas Anda. Sebaliknya, toStringmetode ini dimaksudkan untuk membuat string yang mewakili nilai instance kelas Anda, melaporkan setidaknya pada bidang data terpenting yang disimpan dalam objek itu. Dalam kebanyakan kasus, toStringdigunakan untuk debugging dan logging, bukan untuk logika bisnis Anda.

Untuk menghasilkan teks yang mewakili nilai suatu objek untuk ditampilkan kepada pengguna, tambahkan metode lain. Orang sering menamai metode tersebut seperti getDisplayName. Misalnya, DayOfWeek::getDisplayNamedan Month::getDisplayName.

StringJoiner

Mulai Java 8 dan yang lebih baru, cara paling modern untuk mengimplementasikan toStringakan menggunakan StringJoinerkelas. Seperti yang dikatakan dokter:

StringJoiner digunakan untuk membuat urutan karakter yang dipisahkan oleh pemisah dan secara opsional dimulai dengan prefiks yang disediakan dan diakhiri dengan sufiks yang disediakan.

Gunakan seperti ini:

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

Orang [name = Alice | telepon = 555.867.5309]

Basil Bourque
sumber
1
itu lebih elegan
esQmo_
2

Kode berikut adalah contoh. Berdasarkan pertanyaan yang sama, alih-alih menggunakan konversi berbasis IDE, adakah cara yang lebih cepat untuk mengimplementasikannya sehingga di masa depan terjadi perubahan, kita tidak perlu mengubah nilainya berulang kali?

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

Jika Anda tertarik dengan Unit-Tests, maka Anda dapat mendeklarasikan "ToStringTemplate" publik, dan kemudian Anda dapat menguji unit toString Anda. Bahkan jika Anda tidak mengujinya, saya pikir ini "lebih bersih" dan menggunakan 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());
    } 
}

Sekarang Anda dapat menguji unit dengan membuat Kid, mengatur properti, dan melakukan string.format Anda sendiri di ToStringTemplate dan membandingkan.

membuat ToStringTemplate static-final berarti "SATU VERSI" kebenaran, daripada memiliki "salinan" template di unit-test.

granadaCoder
sumber
1

Sebenarnya Anda perlu mengembalikan sesuatu seperti ini karena toString harus mengembalikan sebuah string

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

dan Anda benar-benar melakukan sesuatu yang salah dalam pembuatnya, Anda menetapkan variabel yang ditetapkan pengguna ke nama sementara Anda perlu melakukan yang sebaliknya. Apa yang tidak boleh Anda lakukan

n = this.name

Apa yang harus Anda lakukan

this.name = n

Semoga ini membantu terima kasih

Mohamed Sherif Noureldin
sumber
1

kita bahkan dapat menulis seperti ini dengan membuat objek String baru di kelas dan menugaskannya apa pun yang kita inginkan di konstruktor dan mengembalikannya ke metode toString yang diganti

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()  
 }  
}
pengguna7321815
sumber
1

Cara yang bagus dan ringkas adalah dengan menggunakan anotasi Lombok. Ini memiliki @ToStringanotasi, yang akan menghasilkan implementasi toString()metode. Secara default, ini akan mencetak nama kelas Anda, bersama dengan setiap bidang, secara berurutan, dipisahkan dengan koma. Anda dapat dengan mudah menyesuaikan keluaran Anda dengan meneruskan parameter ke anotasi, misalnya:

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

Yang setara dengan Java murni:

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

Jika Anda hanya menggunakan toString()untuk men-debug DTO , Anda dapat menghasilkan keluaran yang dapat dibaca manusia secara otomatis dengan sesuatu seperti berikut:

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

Namun, ini tidak sesuai untuk penerapan produksi jika DTO mungkin berisi PII (yang tidak boleh direkam dalam log).

Brent Bradburn
sumber
1

Selalu punya cara mudah: Klik Kanan > Generate > toString () > pilih template yang Anda inginkan. masukkan deskripsi gambar di sini

logbasex
sumber
0

Cara terbaik menurut saya adalah menggunakan perpustakaan google gson:

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

atau apache commons lang refleksi cara

pengguna666
sumber
0
  1. jika Anda menggunakan notepad: lalu

    public String toString(){
    
     return ""; ---now here you can use variables which you have created for your class
    
    }
    
  2. jika Anda menggunakan eclipse IDE, tekan

    -alt +shift +s 
    

    -klik metode override toString di sini Anda akan mendapatkan opsi untuk memilih jenis variabel yang ingin Anda pilih.

The Guy
sumber