Как использовать метод toString в Java?

118

Может ли кто-нибудь объяснить мне концепцию toString()метода, определенного в Objectклассе? Как он используется и для чего?

Дэвид Браун
источник
вот и быстрый трюк / быстрая реализация: @Override public String toString () {return org.apache.commons.lang3.builder.ToStringBuilder.reflectionToString (this); }
granadaCoder 01

Ответы:

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:

Всякий раз, когда вам нужно изучить конструктор с именем value в 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это не предназначено и не подходит для пользовательского интерфейса.
Powerslave
@Powerslave тогда объясните, почему все компоненты Swing используются toStringдля отображения объекта в графическом интерфейсе? Если у меня есть богатый объект, и я хочу показать его в графическом интерфейсе, то нет, я не создаю для него дополнительный рендерер и не извлекаю строковое свойство из объекта, чтобы использовать его в графическом интерфейсе, я сохраняю его прост и реализован, toStringчтобы можно было обойти все эти накладные расходы. Если вы хотите сделать это более чистым способом, создайте класс-оболочку, который предназначен для пользовательского интерфейса и реализует его toStringметод для возврата строкового свойства обертки.
Timmos
1
@Timmos Если бы твои друзья спрыгнули с моста, ты бы последовал за ними? Тот факт, что разработчики Swing используют (читать; злоупотреблять) функцию toString, не означает, что вы тоже должны это делать.
Toby
2
Это, безусловно, самый простой способ выполнить работу, учитывая, что вы продолжаете использовать Swing API по умолчанию. Если вам нужен пользовательский рендеринг, хорошо, установите пользовательский рендерер на свой компонент. Если вы просто хотите отобразить объект, представленный строкой, то реализовать toString () намного проще по сравнению с настраиваемым средством визуализации, у которого есть все возможные подводные камни, чтобы сделать это правильно. Я считаю странным ваше сравнение с прыжком с моста.
Timmos
35

toString()Метод возвращает текстовое представление объекта. Базовая реализация уже включена, java.lang.Objectпоэтому, поскольку все объекты, унаследованные от java.lang.Objectнее, гарантируется, что каждый объект в Java имеет этот метод.

Переопределение метода всегда является хорошей идеей, особенно когда речь идет об отладке, потому что отладчики часто показывают объекты по результату toString()метода. Так что используйте осмысленную реализацию, но используйте ее в технических целях. Логика приложения должна использовать геттеры:

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
не могли бы вы уточнить свое последнее заявление?
Жан-Филипп Каруана,
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 () в классе Coordinates, как показано ниже,

@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. Предоставьте средства доступа / средства получения для всех полей экземпляра, содержащихся в возвращаемой строке. Например, в классе "Координаты"

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

Подробное описание метода toString () содержится в пункте 10 книги «Эффективная Java ™, второе издание» Джоша Блоха.

sxnamit
источник
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 Бхаджи]

Если вы не используете toString () в классе Pojo (Student.java), вы получите результат вроде. [com.steve.test.Student@6e1408, com.steve.test.Student@e53108]Чтобы избежать подобных проблем, мы используем метод toString ().

Стив
источник
4

Всякий раз, когда вы обращаетесь к объекту (не являющемуся String) в контексте String, компилятор вызывает под крышкой toString ().

Вот почему

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

работает, и, переопределив стандартный toString () из Object в ваших собственных классах, вы также можете сделать свои объекты полезными в контекстах String.

(и считайте это черным ящиком! Никогда, никогда не используйте содержимое для чего-либо другого, кроме как для презентации человеку)

Торбьёрн Равн Андерсен
источник
3

Правильно переопределенный метод toString может помочь при ведении журнала и отладке Java.

USM167
источник
2

Помимо того, что Клетус ответил относительно отладки, он используется всякий раз, когда вы выводите объект, например, когда вы используете

 System.out.println(myObject);

или

System.out.println("text " + myObject);
Фрэнк
источник
1

Основная цель toString - создать строковое представление объекта, то есть возвращаемое значение всегда является строкой. В большинстве случаев это просто класс объекта и имя пакета, но в некоторых случаях, например StringBuilder, вы фактически получаете текст 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();
}
redestructa
источник
0

Если вы сначала изучите Python, а затем Java. Я думаю, что он играет ту же роль, что и __str__()метод в Python, это волшебный метод, подобный __dict__()и, __init__()но для ссылки на строку, представляющую объект.

Лернер Чжан
источник
-1

toString()преобразует указанный объект в строковое значение.

Анкит
источник