Jak korzystać z metody toString w Javie?


118

Czy ktoś może mi wyjaśnić koncepcję toString()metody zdefiniowaną w Objectklasie? Jak jest używany i jaki jest jego cel?



oto szybka sztuczka / szybka implementacja: @Override public String toString () {return org.apache.commons.lang3.builder.ToStringBuilder.reflectionToString (this); }
granadaCoder

Odpowiedzi:


81

Z Object.toStringdokumentów:

Zwraca ciąg znaków reprezentujący obiekt. Ogólnie toString metoda zwraca łańcuch, który „tekstowo reprezentuje” ten obiekt. Wynik powinien być zwięzły, ale pouczający i łatwy do odczytania przez osobę. Zaleca się, aby wszystkie podklasy przesłaniały tę metodę.

toStringMetoda klasy Object zwraca ciąg składający się z nazwą klasy, której obiekt jest instancją, postać `at-znak @” oraz unsigned reprezentację szesnastkową kodu hash obiektu. Innymi słowy, ta metoda zwraca ciąg równy wartości:

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

Przykład:

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

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

1
Głównym celem jest zastąpienie go w podklasach. Myślę, że odpowiedzi od @stephen i Andreas_D są lepsze niż zaakceptowana odpowiedź.
Sree Rama,

39

Korzystanie z String.toString:

Ilekroć potrzebujesz zbadać konstruktora o nazwie value w Stringformularzu, możesz po prostu użyć String.toString... na przykład ...

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

}

... skopiuj ten program do swojego Eclipse i uruchom go ... otrzymasz pomysły dotyczące String.toString...


5
Mam nadzieję, że wiesz, że toStringnie jest to przeznaczone i nieodpowiednie do celów interfejsu użytkownika.
Powerslave

@Powerslave następnie wyjaśnij, dlaczego wszystkie komponenty Swing używają toStringdo wyświetlania obiektu w GUI? Jeśli mam bogaty obiekt i chcę go pokazać w GUI, to nie, nie tworzę dla niego dodatkowego renderera ani nie wyodrębniam właściwości ciągu z obiektu, aby użyć go w GUI, zachowuję to proste i wdrażane, toStringaby móc obejść wszystkie te koszty. Jeśli chcesz to zrobić w bardziej przejrzysty sposób, utwórz klasę opakowującą, która jest dedykowana do celów interfejsu użytkownika, i zaimplementuj jej toStringmetodę, aby zwrócić właściwość string elementu opakowującego.
Timmos

1
@Timmos Gdyby twoi przyjaciele zeskoczyli z mostu, poszedłbyś za nim? Tylko dlatego, że programiści Swing używają (czytaj; nadużywaj) funkcji toString, nie oznacza, że ​​Ty też powinieneś.
Toby Caulk

2
Jest to zdecydowanie najłatwiejsze podejście do wykonania zadania, biorąc pod uwagę, że nadal używasz domyślnego interfejsu API Swing. Jeśli chcesz renderować niestandardowe, w porządku, zainstaluj niestandardowy moduł renderujący w swoim komponencie. Jeśli chcesz po prostu wyświetlić obiekt reprezentowany przez String, implementacja metody toString () jest znacznie łatwiejsza w porównaniu z niestandardowym rendererem, który ma wszystkie rodzaje pułapek, aby zrobić to dobrze. Myślę, że twoje porównanie ze skakaniem z mostu jest dziwne.
Timmos

35

toString()Metoda zwraca tekstową reprezentację obiektu. Podstawowa implementacja jest już zawarta w programie, java.lang.Objectwięc ponieważ wszystkie obiekty po niej dziedziczą java.lang.Object, gwarantujemy, że każdy obiekt w Javie ma tę metodę.

Zastępowanie metody jest zawsze dobrym pomysłem, szczególnie jeśli chodzi o debugowanie, ponieważ debuggery często pokazują obiekty według wyniku toString()metody. Więc używaj sensownej implementacji, ale używaj jej do celów technicznych . Logika aplikacji powinna używać metod pobierających:

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

Opcjonalnie może mieć zastosowania w kontekście aplikacji, ale znacznie częściej jest używany do celów debugowania. Na przykład, gdy trafisz w punkt przerwania w środowisku IDE, o wiele łatwiej jest odczytać znaczenie toString()obiektów niż sprawdzić ich członków.

Nie ma określonych wymagań co do tego, co toString()powinna robić metoda. Zgodnie z konwencją, najczęściej podaje nazwę klasy i wartość odpowiednich członków danych. Najczęściej toString()metody są generowane automatycznie w IDE.

Poleganie na określonym wyjściu toString()metody lub analizowanie go w programie to zły pomysł. Cokolwiek robisz, nie idź tą drogą.


2
czy mógłbyś rozwinąć swoje ostatnie stwierdzenie?
Jean-Philippe Caruana,

13

toString () zwraca łańcuchową / tekstową reprezentację obiektu. Metoda toString (), często używana do celów diagnostycznych, takich jak debugowanie, rejestrowanie itp., Służy do odczytywania istotnych szczegółów obiektu.

Jest wywoływana automatycznie, gdy obiekt jest przekazywany do println, print, printf, String.format (), assert lub operatora konkatenacji ciągów.

Domyślna implementacja toString () w klasie Object zwraca ciąg znaków składający się z nazwy klasy tego obiektu, po którym następuje znak @ oraz reprezentację szesnastkową bez znaku kodu skrótu tego obiektu przy użyciu następującej logiki,

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

Na przykład następujące

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

wydruki

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

Teraz, zastępując toString () w klasie Coordinates, jak poniżej,

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

prowadzi do

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

Przydatność przesłaniania metody toString () staje się jeszcze większa, gdy metoda jest wywoływana na kolekcjach zawierających odwołania do tych obiektów. Na przykład następujące

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

wydruki

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

zamiast tego,

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

Kilka wskazówek dotyczących implementacji,

  1. Prawie zawsze należy przesłonić metodę toString (). Jednym z przypadków, w których przesłonięcie nie byłoby wymagane, są klasy narzędziowe, które grupują statyczne metody narzędziowe w sposób java.util.Math . Przypadek, gdy przesłonięcie nie jest wymagane, jest dość intuicyjny; prawie zawsze byś wiedział.
  2. Zwracany ciąg powinien być zwięzły i informacyjny, najlepiej nie wymagający objaśnień.
  3. Przynajmniej pola używane do ustalenia równoważności między dwoma różnymi obiektami, tj. Pola używane w implementacji metody equals () , powinny być wypluwane metodą toString ().
  4. Podaj metody dostępu / metody pobierające dla wszystkich pól wystąpienia, które są zawarte w zwracanym ciągu. Na przykład w klasie Współrzędne

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

Obszerne omówienie metody toString () znajduje się w punkcie 10 książki, Effective Java ™, Second Edition, Josh Bloch.


6

Kodowanie:

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

Wynik:

[Steve 12 Daniel, Sachin 10 Tendulkar]

[Steve 12 Daniel, Sachin 10 Tendulkar, Yuvi 12 Bhajji]

Jeśli nie jesteś przyzwyczajony do toString () w klasie Pojo (Student.java), otrzymasz wynik w rodzaju [com.steve.test.Student@6e1408, com.steve.test.Student@e53108].Aby uniknąć tego typu problemów, używamy metody toString ().


4

Za każdym razem, gdy uzyskujesz dostęp do obiektu (nie będącego Stringiem) w kontekście String, kompilator wywołuje metodę toString () pod osłonami.

Dlatego

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

działa, a przesłaniając standardową metodę toString () z Object we własnych klasach, możesz sprawić, że obiekty będą użyteczne również w kontekstach String.

(i potraktuj to jako czarne pudełko! Nigdy, przenigdy nie używaj zawartości do niczego innego niż prezentacja człowiekowi)


3

Prawidłowo nadpisana metoda toString może pomóc w rejestrowaniu i debugowaniu języka Java.


2

Oprócz tego, na co Cletus odpowiedział w odniesieniu do debugowania, jest on używany zawsze, gdy wyprowadzasz obiekt, na przykład podczas używania

 System.out.println(myObject);

lub

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

1

Głównym celem toString jest wygenerowanie String reprezentacji obiektu, co oznacza, że ​​zwracaną wartością jest zawsze String. W większości przypadków jest to po prostu klasa obiektu i nazwa pakietu, ale w niektórych przypadkach, takich jak StringBuilder, otrzymasz w rzeczywistości tekst typu String.


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

Jeśli najpierw nauczysz się języka Python, a następnie języka Java. Myślę, że odgrywa taką samą rolę jak __str__()metoda w Pythonie, jest to magiczna metoda podobna do __dict__()i, __init__()ale odnosząca się do ciągu znaków reprezentującego obiekt.


-1

toString()konwertuje określonego obiektu na wartość ciągu.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.