Como usar o método toString em Java?

118

Alguém pode me explicar o conceito do toString()método, definido na Objectaula? Como é usado e para que serve?

David Brown
fonte
aqui está um truque / implementação rápida também: @Override public String toString () {return org.apache.commons.lang3.builder.ToStringBuilder.reflectionToString (this); }
granadaCoder

Respostas:

81

Dos Object.toStringdocumentos:

Retorna uma representação de string do objeto. Em geral, o toString método retorna uma string que "representa textualmente" este objeto. O resultado deve ser uma representação concisa, mas informativa, de fácil leitura para uma pessoa. É recomendável que todas as subclasses substituam esse método.

O toStringmétodo para class Object retorna uma string que consiste no nome da classe da qual o objeto é uma instância, o caractere arroba `@ 'e a representação hexadecimal sem sinal do código hash do objeto. Em outras palavras, este método retorna uma string igual ao valor de:

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

Exemplo:

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

output:- mystr.toString: [Ljava.lang.String;@13aaa14a
Sean Patrick Floyd
fonte
1
O objetivo principal é substituí-lo nas subclasses. Acho que as respostas de @stephen e Andreas_D são melhores do que uma resposta aceita.
Sree Rama
39

Uso de String.toString:

Sempre que precisar explorar o construtor chamado valor no Stringformulário, você pode simplesmente usar String.toString... para um exemplo ...

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

}

... copie este programa em seu Eclipse e execute-o ... você obterá as idéias sobre String.toString...

Naseem Afzal
fonte
5
Espero que você esteja ciente de que toStringnão se destina e não é adequado para fins de interface do usuário.
Powerslave,
@Powerslave então explica por que todos os componentes Swing estão usando toStringpara exibir um objeto na GUI? Se eu tenho um objeto rico e quero mostrá-lo em uma GUI, então não, eu não crio um renderizador extra para ele nem extraio uma propriedade de string do objeto para usar na GUI, eu a mantenho simples e implementa toStringpara poder contornar toda essa sobrecarga. Se você quiser fazer isso de uma maneira mais limpa, crie uma classe de invólucro que seja dedicada para fins de IU e implemente seu toStringmétodo para retornar uma propriedade de string do invólucro.
Timmos
1
@Timmos Se seus amigos pulassem de uma ponte, você o seguiria? Só porque os desenvolvedores do Swing usam (leia; abuse), a função toString não significa que você também deve usar.
Toby Caulk
2
É de longe a abordagem mais fácil para realizar o trabalho, visto que você continua usando a API Swing padrão. Se você quiser renderização customizada, tudo bem, instale um renderizador customizado em seu componente. Se você deseja apenas exibir um objeto representado por uma String, implementar toString () é muito mais fácil em comparação com um renderizador personalizado, que tem todos os tipos de armadilhas para fazer isso da maneira certa. Acho que sua comparação com pular de uma ponte é estranha.
Timmos
35

O toString()método retorna uma representação textual de um objeto. Uma implementação básica já está incluída em java.lang.Objecte, portanto, como todos os objetos herdam java.lang.Objectdela, é garantido que todo objeto em Java possui este método.

Substituir o método é sempre uma boa ideia, especialmente quando se trata de depuração, porque os depuradores geralmente mostram objetos pelo resultado do toString()método. Portanto, use uma implementação significativa, mas use-a para fins técnicos . A lógica do aplicativo deve usar 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()+"]";
  }
}
Andreas Dolk
fonte
14

Ele pode opcionalmente ter usos dentro do contexto de um aplicativo, mas com muito mais freqüência é usado para fins de depuração. Por exemplo, quando você atinge um ponto de interrupção em um IDE, é muito mais fácil ler um ponto de interrupção significativotoString() objetos do que inspecionar seus membros.

Não há um requisito definido para o que um toString()método deve fazer. Por convenção, na maioria das vezes ele informará o nome da classe e o valor dos membros de dados pertinentes. Na maioria das vezes, os toString()métodos são gerados automaticamente em IDEs.

Depender de uma saída específica de um toString()método ou analisá-la dentro de um programa é uma má ideia. Faça o que fizer, não vá por esse caminho.

cletus
fonte
2
você poderia elaborar sua última declaração?
Jean-Philippe Caruana de
13

toString () retorna uma string / representação textual do objeto. Normalmente usado para fins de diagnóstico, como depuração, registro, etc., o método toString () é usado para ler detalhes significativos sobre o objeto.

Ele é chamado automaticamente quando o objeto é passado para println, print, printf, String.format (), assert ou o operador de concatenação de string.

A implementação padrão de toString () na classe Object retorna uma string que consiste no nome da classe deste objeto seguido pelo sinal @ e a representação hexadecimal sem sinal do código hash deste objeto usando a seguinte lógica,

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

Por exemplo, o seguinte

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

estampas

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

Agora, substituindo toString () na classe Coordinates como abaixo,

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

resulta em

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

A utilidade de substituir toString () torna-se ainda mais quando o método é invocado em coleções que contêm referências a esses objetos. Por exemplo, o seguinte

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

estampas

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

em vez disso,

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

Poucos indicadores de implementação,

  1. Você quase sempre deve substituir o método toString (). Um dos casos em que a substituição não seria necessária são as classes de utilitários que agrupam métodos de utilitários estáticos, na forma de java.util.Math . O caso de não ser necessário substituir é bastante intuitivo; quase sempre você saberia.
  2. A string retornada deve ser concisa e informativa, idealmente autoexplicativa.
  3. Pelo menos, os campos usados ​​para estabelecer equivalência entre dois objetos diferentes, isto é, os campos usados ​​na implementação do método equals () devem ser cuspidos pelo método toString ().
  4. Fornece acessadores / getters para todos os campos de instância contidos na string retornada. Por exemplo, na classe Coordenadas,

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

Uma cobertura abrangente do método toString () está no Item 10 do livro Effective Java ™, Second Edition, de Josh Bloch.

sxnamit
fonte
6

Codificação:

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

Resultado:

[Steve 12 Daniel, Sachin 10 Tendulkar]

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

Se você não está acostumado com toString () na classe Pojo (Student.java), você receberá uma saída como [com.steve.test.Student@6e1408, com.steve.test.Student@e53108]. Para evitar esse tipo de problema, estamos usando o método toString ().

Steve
fonte
4

Sempre que você acessa um objeto (não sendo uma string) em um contexto de string, o toString () é chamado de forma oculta pelo compilador.

Isso é por que

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

funciona, e substituindo o toString () padrão de Object em suas próprias classes, você pode tornar seus objetos úteis também em contextos de String.

(e considere isso uma caixa preta! Nunca, jamais use o conteúdo para outra coisa senão apresentar a um humano)

Thorbjørn Ravn Andersen
fonte
3

O método toString substituído corretamente pode ajudar na criação de log e depuração de Java.

USM167
fonte
2

Além do que cletus respondeu com relação à depuração, ele é usado sempre que você produz um objeto, como quando você usa

 System.out.println(myObject);

ou

System.out.println("text " + myObject);
Frank
fonte
1

O objetivo principal de toString é gerar uma representação String de um objeto, o que significa que o valor de retorno é sempre uma String. Na maioria dos casos, este é simplesmente a classe do objeto e o nome do pacote, mas em alguns casos, como StringBuilder, você obterá na verdade um String-text.

heb
fonte
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();
}
redestructa
fonte
0

Se você aprender Python primeiro e depois Java. Eu acho que ele desempenha o mesmo papel que o __str__()método em Python, é um método mágico como __dict__()e, __init__()mas para se referir a uma string que representa o objeto.

Lerner Zhang
fonte
-1

o toString()converte o objeto especificado em um valor de string.

ankit
fonte