Java'da toString () nasıl düzgün şekilde geçersiz kılınır?


88

Biraz aptalca geliyor ama toString()yöntemim konusunda yardıma ihtiyacım var ve bu çok sinir bozucu. İnternette bakmaya çalıştım çünkü toStringçuvalladığı ve orada olmasına rağmen "Kid kurucusunu bulamama" olduğu ve başka bir şey yapacağım ve işe yaramadığı yer. Tamam bu çok fazlaydı, işte kodum:

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 

Tamam Yani yukarıdaki toString'im (biliyorum, üçüncü parametrem kapalı, String olmalı) kapalı. Üçüncü şey için bir değeri kodlarsam, karışık olur ve bunu bulamadığını söyler (yukarıda). Öyleyse tarihi nasıl bulabilirim ve onu nasıl bölebilirim?

Bunu arayan sınıf aşağıdadır

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  

Birden fazla kurucu araştırmayı denedim ve gerçekten yardımcı olmadı. toString()Yöntemleri araştırmayı denedim ve daha önce toString()oluşturduğum önceki yöntem mantığını kullanmayı denedim ama bu yepyeni, bu yüzden hiç işe yaramadı.

Yardım?


5
Lütfen gerçekten derlenecek kodu gönderin. Kişisel toString()yöntem bir dize dönmez ve böyle bir kurucu diyemezsin. Ne başarmaya çalıştığın bile belli değil. Lütfen tinyurl.com/so-hints adresini okuyun ve sorunuzu netleştirin.
Jon Skeet

Spring'in ToStringCreator'ı ( github.com/SpringSource/spring-framework/tree/master/… ) işi çok güzel yapıyor.
Ritesh

Bilginize gibi korkunç zahmetli eski tarih-saat sınıfları java.util.Date, java.util.GregorianCalendarve java.text.SimpleDateFormatşimdi mirası supplanted, java.time sonra Java 8 ve yerleşik sınıflara. Oracle'ın Eğitimine bakın .
Basil Bourque

Yanıtlar:


136

A toStringdöndürmesi gerekiyor String.

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

toStringYöntemi oluşturmak için IDE'nizin özelliklerinden yararlanmanızı öneririm . Elle kodlamayın.

Örneğin, Eclipse, kaynak koda sağ tıklayıp Source > Generate toString


1
Dize birleştirme kullandığınız için bu iyi bir uygulama değildir.
Amit

1
StringBuilder, böyle bir durumda daha iyi bir seçimdir.
Amit

9
@Amit Java derleyicisi StringBuilderörtük olarak kullanır . Bir döngüde kullanmadığınız sürece sorun yok.
chrylis

Netbeans'te; daha Source -> Insert Code...sonra seçintoString
Fer

11

Java toString () yöntemi

Herhangi bir nesneyi bir dizge olarak temsil etmek isterseniz, toString () yöntemi ortaya çıkar.

ToString () yöntemi, nesnenin dize gösterimini döndürür.

Herhangi bir nesneyi yazdırırsanız, java derleyici dahili olarak nesne üzerinde toString () yöntemini çağırır. Dolayısıyla, toString () yöntemini geçersiz kılmak istenen çıktıyı döndürür, bir nesnenin durumu olabilir vb. Uygulamanıza bağlıdır.

Java toString () yönteminin avantajı

Object sınıfının toString () yöntemini geçersiz kılarak, nesnenin değerlerini döndürebiliriz, böylece çok fazla kod yazmamıza gerek kalmaz.

ToString () yöntemi olmadan çıktı

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

Yukarıdaki 1. örnekte görebilirsiniz. s1 ve s2 yazdırmak nesnelerin Hashcode değerlerini yazdırıyor ancak bu nesnelerin değerlerini yazdırmak istiyorum. Java derleyicisi dahili olarak toString () yöntemini çağırdığından, bu yöntemin geçersiz kılınması belirtilen değerleri döndürür. Bunu aşağıda verilen örnekle anlayalım:

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 () 'in çoğunlukla Java'daki polimorfizm kavramıyla ilgili olduğuna dikkat edin. Eclipse'de, toString () 'e tıklayıp sağ tıklayıp, ardından Açık Bildirime tıklayın ve Superclass toString ()' in nereden geldiğini görün.


4

ToString () içinde yeni nesne oluşturabilirsiniz. kullanım

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

onun yerine

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

Dönüş dizesini gerektiği gibi değiştirebilirsiniz. Takvim yerine tarihi saklamanın başka yolları da var.


3

Bir kurucuyu normal bir yöntemmiş gibi çağıramazsınız, sadece newyeni bir nesne oluşturmak için çağırabilirsiniz :

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

Ancak toString () yönteminizden yeni bir nesne oluşturmak, yapmak istediğiniz şey değildir.


3

Başkalarının da açıkladığı gibi, toStringsınıfınızı somutlaştırmanın yeri burası değildir. Bunun yerine, toStringyöntemin, sınıfınızın bir örneğinin değerini temsil eden ve o nesnede depolanan verilerin en azından en önemli alanlarını raporlayan bir dize oluşturması amaçlanmıştır. Çoğu durumda,toString iş mantığınız için değil, hata ayıklama ve günlük kaydı için kullanılır.

Bir kullanıcıya gösterilmek üzere bir nesnenin değerini temsil eden metin oluşturmak için başka bir yöntem ekleyin. İnsanlar yöntemi genellikle şöyle adlandırırlar getDisplayName. Örneğin DayOfWeek::getDisplayNameve Month::getDisplayName.

StringJoiner

Java 8 ve sonraki sürümlerden itibaren, uygulamanın en modern yolu sınıfı toStringkullanır StringJoiner. Doktorun dediği gibi:

StringJoiner, bir sınırlayıcı ile ayrılmış ve isteğe bağlı olarak sağlanan bir önek ile başlayıp sağlanan bir sonek ile biten bir karakter dizisi oluşturmak için kullanılır.

Bunun gibi kullanın:

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

Kişi [name = Alice | telefon = 555.867.5309]


1
bu daha zarif
esQmo_

2

Aşağıdaki kod bir örnektir. IDE tabanlı dönüştürme kullanmak yerine aynı soruyu temel alan, gelecekte değişikliklerin gerçekleşmesi için değerleri tekrar tekrar değiştirmemize gerek kalmaması için uygulamanın daha hızlı bir yolu var mı?

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

2

Unit-Tests ile ilgileniyorsanız, o zaman genel bir "ToStringTemplate" ilan edebilir ve sonra toString'inizi birim test edebilirsiniz. Birim testi yapmasanız bile, bence "daha temiz" ve String.format kullanıyor.

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

Artık Kid'i oluşturarak, özellikleri ayarlayarak ve ToStringTemplate üzerinde kendi string.format dosyanızı yaparak ve karşılaştırarak birim testi yapabilirsiniz.

ToStringTemplate'in statik son haline getirilmesi, birim testinde şablonun bir "kopyasına" sahip olmak yerine gerçeğin "BİR SÜRÜMÜ" anlamına gelir.


1

Aslında böyle bir şey döndürmeniz gerekecek çünkü toString'in bir dizge döndürmesi gerekiyor

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

ve yapıcıda aslında yanlış bir şey yaparsınız, kullanıcının isme ayarladığı değişkeni tam tersini yapmanız gerekirken ayarlarsınız. Ne yapmamalısın

n = this.name

Ne yapmalısın

this.name = n

Bunun yardımcı olacağını umuyorum teşekkürler


1

sınıfta yeni bir String nesnesi oluşturarak ve onu yapıcıda istediğimizi atayarak ve bunu geçersiz kılınan toString yöntemine döndürerek bile böyle yazabiliriz

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

Güzel ve özlü yol, Lombok açıklamalarını kullanmaktır. Yöntemin @ToStringbir uygulamasını oluşturacak ek açıklamaya sahiptir toString(). Varsayılan olarak, sınıf adınızı her alanla birlikte virgülle ayırarak sırayla yazdıracaktır. Ek açıklamaya parametreler ileterek çıktınızı kolayca özelleştirebilirsiniz, örneğin:

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

Saf Java'ya eşdeğer olan:

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

1

Yalnızca toString()bir DTO'da hata ayıklamak için kullanıyorsanız , aşağıdakine benzer bir şeyle otomatik olarak insan tarafından okunabilir çıktı oluşturabilirsiniz :

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

Ancak, DTO PII (günlüklere kaydedilmemelidir) içerebiliyorsa, bu üretim dağıtımları için uygun değildir.


1

Her zaman kolay yol: Sağ Tık > Oluştur > toString () > istediğiniz şablonu seçin. görüntü açıklamasını buraya girin


0

Bence en iyi yol google gson kitaplığını kullanmak:

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

veya apache commons lang yansıma yolu


0
  1. not defteri kullanıyorsanız: o zaman

    public String toString(){
    
     return ""; ---now here you can use variables which you have created for your class
    
    }
    
  2. eclipse IDE kullanıyorsanız

    -alt +shift +s 
    

    -Burada toString yöntemini geçersiz kıl'a tıklayın, hangi tür değişkenleri seçmek istediğinizi seçmek için seçenekler göreceksiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.