วิธีการใช้ toString ใน Java


118

ใครช่วยอธิบายแนวคิดของtoString()วิธีการที่กำหนดไว้ในObjectคลาสให้ฉันได้ไหม มันใช้อย่างไรและมีจุดประสงค์อะไร?



นี่คือเคล็ดลับอย่างรวดเร็ว / การนำไปใช้อย่างรวดเร็วเช่นกัน: @Override public String toString () {return org.apache.commons.lang3.builder ToStringBuilder.reflectionToString (this); }
granadaCoder

คำตอบ:


81

จากObject.toStringเอกสาร:

ส่งกลับการแสดงสตริงของวัตถุ โดยทั่วไปtoString เมธอดจะส่งคืนสตริงที่ "แสดงข้อความ" วัตถุนี้ ผลลัพธ์ควรเป็นการนำเสนอที่กระชับ แต่ให้ข้อมูลที่ง่ายสำหรับคนที่จะอ่าน ขอแนะนำให้คลาสย่อยทั้งหมดแทนที่เมธอดนี้

toStringวิธีการสำหรับการเรียนObject ส่งกลับสตริงประกอบด้วยชื่อของคลาสซึ่งวัตถุที่เป็นเช่นที่ป้ายตัวอักษร `@' และการแสดงที่ไม่ได้ลงชื่อเลขฐานสิบหกรหัสกัญชาของวัตถุ กล่าวอีกนัยหนึ่งวิธีนี้จะส่งคืนสตริงที่เท่ากับค่าของ:

getClass().getName() + '@' + Integer.toHexString(hashCode())

ตัวอย่าง:

String[] mystr ={"a","b","c"};
System.out.println("mystr.toString: " + mystr.toString());

output:- mystr.toString: [Ljava.lang.String;@13aaa14a

1
จุดประสงค์หลักคือการลบล้างในคลาสย่อย ฉันคิดว่าคำตอบจาก @stephen และ Andreas_D ดีกว่าคำตอบที่ยอมรับ
ศรีพระราม

39

การใช้String.toString:

เมื่อใดก็ตามที่คุณต้องการสำรวจตัวสร้างที่เรียกว่าค่าในStringรูปแบบคุณสามารถใช้String.toString... ตัวอย่าง ...

package pack1;

import java.util.*;

class Bank {

    String n;
    String add;
    int an;
    int bal;
    int dep;

    public Bank(String n, String add, int an, int bal) {

        this.add = add;
        this.bal = bal;
        this.an = an;
        this.n = n;

    }

    public String toString() {
        return "Name of the customer.:" + this.n + ",, "
                + "Address of the customer.:" + this.add + ",, " + "A/c no..:"
                + this.an + ",, " + "Balance in A/c..:" + this.bal;
    }
}

public class Demo2 {

    public static void main(String[] args) {

        List<Bank> l = new LinkedList<Bank>();

        Bank b1 = new Bank("naseem1", "Darbhanga,bihar", 123, 1000);
        Bank b2 = new Bank("naseem2", "patna,bihar", 124, 1500);
        Bank b3 = new Bank("naseem3", "madhubani,bihar", 125, 1600);
        Bank b4 = new Bank("naseem4", "samastipur,bihar", 126, 1700);
        Bank b5 = new Bank("naseem5", "muzafferpur,bihar", 127, 1800);
        l.add(b1);
        l.add(b2);
        l.add(b3);
        l.add(b4);
        l.add(b5);
        Iterator<Bank> i = l.iterator();
        while (i.hasNext()) {
            System.out.println(i.next());
        }
    }

}

... คัดลอกโปรแกรมนี้ลงใน Eclipse ของคุณและเรียกใช้ ... คุณจะได้รับแนวคิดเกี่ยวกับString.toString...


5
ฉันหวังว่าคุณจะทราบtoStringว่าไม่ได้ตั้งใจและไม่เหมาะสำหรับวัตถุประสงค์ของ UI
Powerslave

@Powerslave อธิบายว่าเหตุใดส่วนประกอบ Swing ทั้งหมดจึงใช้toStringเพื่อแสดงวัตถุใน GUI? หากฉันมีวัตถุที่สมบูรณ์และฉันต้องการแสดงใน GUI ไม่ฉันจะไม่สร้างตัวแสดงผลพิเศษสำหรับมันและฉันไม่แยกคุณสมบัติสตริงออกจากวัตถุเพื่อใช้ใน GUI ฉันเก็บไว้ ง่ายและนำtoStringไปใช้เพื่อให้สามารถหลีกเลี่ยงค่าใช้จ่ายทั้งหมดนั้นได้ หากคุณต้องการทำสิ่งนี้ด้วยวิธีที่ชัดเจนยิ่งขึ้นให้สร้างคลาส Wrapper ซึ่งมีไว้สำหรับวัตถุประสงค์ของ UI โดยเฉพาะและใช้toStringเมธอดเพื่อส่งคืนคุณสมบัติสตริงของ wrappee
Timmos

1
@Timmos ถ้าเพื่อนของคุณกระโดดลงจากสะพานคุณจะทำตาม? เพียงเพราะผู้พัฒนา Swing ใช้ (อ่าน; ละเมิด) ฟังก์ชัน toString ไม่ได้หมายความว่าคุณควรทำเช่นกัน
Toby Caulk

2
เป็นวิธีที่ง่ายที่สุดในการทำงานให้เสร็จเนื่องจากคุณใช้ Swing API เริ่มต้นต่อไป หากคุณต้องการการแสดงผลแบบกำหนดเองให้ติดตั้งตัวแสดงผลแบบกำหนดเองบนคอมโพเนนต์ของคุณ หากคุณต้องการแสดงวัตถุที่แสดงด้วย String การใช้ toString () นั้นง่ายกว่าเมื่อเทียบกับตัวแสดงผลแบบกำหนดเองซึ่งมีข้อผิดพลาดทั้งหมดที่จะทำให้ถูกต้อง ฉันคิดว่าการเปรียบเทียบของคุณกับการกระโดดลงจากสะพานเป็นเรื่องแปลก
Timmos

35

toString()วิธีการส่งกลับต้นฉบับเดิมเป็นตัวแทนของวัตถุ การใช้งานพื้นฐานถูกรวมไว้แล้วjava.lang.Objectดังนั้นเนื่องจากอ็อบเจ็กต์ทั้งหมดที่สืบทอดมาจากjava.lang.Objectนั้นรับประกันได้ว่าทุกอ็อบเจ็กต์ใน Java มีเมธอดนี้

การลบล้างเมธอดนั้นเป็นความคิดที่ดีเสมอโดยเฉพาะอย่างยิ่งเมื่อเป็นเรื่องของการดีบักเนื่องจากผู้ดีบั๊กมักจะแสดงวัตถุจากผลลัพธ์ของtoString()เมธอด ดังนั้นใช้การใช้งานที่มีความหมาย แต่ใช้เพื่อวัตถุประสงค์ทางเทคนิค ตรรกะของแอปพลิเคชันควรใช้ getters:

public class Contact {
  private String firstName;
  private String lastName;
  public Contact (String firstName, String lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }
  public String getFirstName() {return firstName;}
  public String getLastName() {return lastName;}

  public String getContact() {
    return firstName + " " + lastName;
  }

  @Override
  public String toString() {
    return "["+getContact()+"]";
  }
}

14

อาจเป็นทางเลือกที่จะใช้ในบริบทของแอปพลิเคชัน แต่มักใช้เพื่อวัตถุประสงค์ในการดีบัก ตัวอย่างเช่นเมื่อคุณกดเบรกพอยต์ใน IDE การอ่านความหมายtoString()ของวัตถุนั้นง่ายกว่าการตรวจสอบสมาชิก

ไม่มีข้อกำหนดที่กำหนดไว้ว่าtoString()วิธีใดควรทำ ตามแบบแผนส่วนใหญ่มักจะบอกชื่อคลาสและมูลค่าของสมาชิกข้อมูลที่เกี่ยวข้อง บ่อยครั้งที่toString()เมธอดถูกสร้างขึ้นโดยอัตโนมัติใน IDE

การใช้ผลลัพธ์เฉพาะจากtoString()วิธีการหรือการแยกวิเคราะห์ภายในโปรแกรมเป็นความคิดที่ไม่ดี ไม่ว่าคุณจะทำอะไรอย่าไปตามเส้นทางนั้น


2
คุณช่วยอธิบายรายละเอียดเกี่ยวกับคำพูดสุดท้ายของคุณได้ไหม
Jean-Philippe Caruana

13

toString ()ส่งคืนการแสดงสตริง / ข้อความของวัตถุ โดยทั่วไปใช้เพื่อวัตถุประสงค์ในการวินิจฉัยเช่นการดีบักการบันทึก ฯลฯ วิธี toString () ใช้เพื่ออ่านรายละเอียดที่มีความหมายเกี่ยวกับวัตถุ

มันถูกเรียกโดยอัตโนมัติเมื่อวัตถุถูกส่งผ่านไปยัง println, print, printf, String.format (), assert หรือตัวดำเนินการต่อสตริง

การใช้งาน toString () ดีฟอลต์ในคลาส Object จะส่งคืนสตริงที่ประกอบด้วยชื่อคลาสของอ็อบเจ็กต์นี้ตามด้วยเครื่องหมาย @ และการแทนค่าเลขฐานสิบหกที่ไม่ได้ลงนามของรหัสแฮชของอ็อบเจ็กต์นี้โดยใช้ตรรกะต่อไปนี้

getClass().getName() + "@" + Integer.toHexString(hashCode())

ตัวอย่างเช่นต่อไปนี้

public final class Coordinates {

    private final double x;
    private final double y;

    public Coordinates(double x, double y) {
        this.x = x;
        this.y = y;
    }

    public static void main(String[] args) {
        Coordinates coordinates = new Coordinates(1, 2);
        System.out.println("Bourne's current location - " + coordinates);
    }
}

พิมพ์

Bourne's current location - Coordinates@addbf1 //concise, but not really useful to the reader

ตอนนี้แทนที่ toString () ในคลาสพิกัดดังต่อไปนี้

@Override
public String toString() {
    return "(" + x + ", " + y + ")";
}

ผลลัพธ์ใน

Bourne's current location - (1.0, 2.0) //concise and informative

ประโยชน์ของการแทนที่ toString () จะมากยิ่งขึ้นเมื่อมีการเรียกใช้เมธอดบนคอลเลกชันที่มีการอ้างอิงถึงอ็อบเจ็กต์เหล่านี้ ตัวอย่างเช่นต่อไปนี้

public static void main(String[] args) {
    Coordinates bourneLocation = new Coordinates(90, 0);
    Coordinates bondLocation = new Coordinates(45, 90);
    Map<String, Coordinates> locations = new HashMap<String, Coordinates>();
    locations.put("Jason Bourne", bourneLocation);
    locations.put("James Bond", bondLocation);
    System.out.println(locations);
}

พิมพ์

{James Bond=(45.0, 90.0), Jason Bourne=(90.0, 0.0)}

แทนที่จะเป็นแบบนี้

{James Bond=Coordinates@addbf1, Jason Bourne=Coordinates@42e816}

ตัวชี้การใช้งานเพียงไม่กี่ตัว

  1. คุณควรแทนที่เมธอด toString () เกือบตลอดเวลา หนึ่งในกรณีที่แทนที่จะไม่จำเป็นต้องใช้เป็นอาคารเรียนว่าวิธีการสาธารณูปโภคกลุ่มแบบคงที่ในลักษณะของjava.util.Math กรณีของการไม่จำเป็นต้องมีการแทนที่นั้นค่อนข้างใช้งานง่าย เกือบตลอดเวลาที่คุณจะรู้
  2. สตริงที่ส่งคืนควรมีความกระชับและให้ข้อมูลอธิบายได้ในตัวเอง
  3. อย่างน้อยฟิลด์ที่ใช้ในการสร้างความเท่าเทียมกันระหว่างสองอ็อบเจ็กต์ที่แตกต่างกันเช่นฟิลด์ที่ใช้ในการใช้เมธอดequals ()ควรคายออกโดยเมธอด toString ()
  4. จัดเตรียม accessors / getters สำหรับฟิลด์อินสแตนซ์ทั้งหมดที่มีอยู่ในสตริงที่ส่งคืน ตัวอย่างเช่นในคลาสพิกัด

    public double getX() {
        return x;
    }
    public double getY() {
        return y;
    }
    

ความครอบคลุมที่ครอบคลุมของวิธี toString () อยู่ในรายการที่ 10 ของหนังสือ Effective Java ™, Second Edition โดย Josh Bloch


6

การเข้ารหัส:

public class Test {

    public static void main(String args[]) {

        ArrayList<Student> a = new ArrayList<Student>();
        a.add(new Student("Steve", 12, "Daniel"));
        a.add(new Student("Sachin", 10, "Tendulkar"));

        System.out.println(a);

        display(a);

    }

    static void display(ArrayList<Student> stu) {

        stu.add(new Student("Yuvi", 12, "Bhajji"));

        System.out.println(stu);

    }

}

Student.java:

public class Student {

    public String name;

    public int id;

    public String email;

    Student() {

    }

    Student(String name, int id, String email) {

        this.name = name;
        this.id = id;
        this.email = email;

    }

     public String toString(){           //using these toString to avoid the output like this [com.steve.test.Student@6e1408, com.steve.test.Student@e53108]
          return name+" "+id+" "+email;     
         }  


    public String getName(){

        return name;
    }

    public void setName(String name){

        this.name=name;
    }

    public int getId(){

        return id;
    }

    public void setId(int id){

        this.id=id;
    }

    public String getEmail(){

        return email;

    }

    public void setEmail(String email){

        this.email=email;
    }
}

เอาท์พุท:

[สตีฟ 12 ดาเนียลซาชิน 10 เทนดุลการ์]

[สตีฟ 12 ดาเนียล, ซาชิน 10 เทนดุลการ์, ยูวี 12 Bhajji]

หากคุณไม่คุ้นเคยกับ toString () ในคลาส Pojo (Student.java) คุณจะได้ผลลัพธ์เช่น[com.steve.test.Student@6e1408, com.steve.test.Student@e53108]เพื่อหลีกเลี่ยงปัญหาประเภทนี้เราใช้เมธอด toString ()


4

เมื่อใดก็ตามที่คุณเข้าถึง Object (ไม่ใช่ String) ในบริบท String toString () จะถูกเรียกภายใต้การครอบคลุมโดยคอมไพเลอร์

นี่คือเหตุผล

Map map = new HashMap();
System.out.println("map=" + map);

ใช้งานได้และโดยการแทนที่มาตรฐาน toString () จาก Object ในคลาสของคุณเองคุณสามารถทำให้วัตถุของคุณมีประโยชน์ในบริบท String ได้เช่นกัน

(และถือว่ามันเป็นกล่องดำ! ไม่เคยใช้เนื้อหาเพื่อสิ่งอื่นใดนอกจากการนำเสนอต่อมนุษย์)


3

เมธอด toString ที่ถูกแทนที่อย่างถูกต้องสามารถช่วยในการบันทึกและการดีบักของ Java


2

นอกเหนือจากสิ่งที่ cletus ตอบเกี่ยวกับการดีบักแล้วยังใช้เมื่อใดก็ตามที่คุณส่งออกวัตถุเช่นเมื่อคุณใช้

 System.out.println(myObject);

หรือ

System.out.println("text " + myObject);

1

จุดประสงค์หลักของ toString คือการสร้างการแสดงสตริงของอ็อบเจ็กต์ซึ่งหมายความว่าค่าที่ส่งคืนจะเป็นสตริงเสมอ ในกรณีส่วนใหญ่นี่เป็นเพียงคลาสของอ็อบเจ็กต์และชื่อแพ็กเกจ แต่ในบางกรณีเช่น StringBuilder คุณจะได้ String-text


0
/**
 * This toString-Method works for every Class, where you want to display all the fields and its values
 */
public String toString() {

    StringBuffer sb = new StringBuffer();

    Field[] fields = getClass().getDeclaredFields(); //Get all fields incl. private ones

    for (Field field : fields){

        try {

            field.setAccessible(true);
            String key=field.getName();
            String value;

            try{
                value = (String) field.get(this);
            } catch (ClassCastException e){
                value="";
            }

            sb.append(key).append(": ").append(value).append("\n");

        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (SecurityException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }

    }

    return sb.toString();
}

0

หากคุณเรียนรู้ Python ก่อนแล้วจึงค่อย Java ฉันคิดว่ามันมีบทบาทเช่นเดียวกับ__str__()วิธีการใน Python มันเป็นเมธอดมายากลเหมือน__dict__()และ__init__()แต่หมายถึงสตริงที่แสดงถึงวัตถุ


โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.