Как изящно распечатать объект Java?

Java

Привет, я Молчаливый Ван Эр, программист ростом с Хуан Цзяджу и красивым, как Энди Лау. Написав код на Java более десяти лет, я до сих пор чувствую себя нубом (позвольте мне стыдиться).

Темной и ветреной ночью в течение месяца, подумав об этом, я почувствовал, что не могу больше быть таким растраченным. Поэтому он принял решение и приготовился форсировать ввод через метод вывода, чтобы развивать свою внутреннюю силу, чтобы стать настоящим богом. В то же время я надеюсь, что эти статьи помогут большему количеству читателей, чтобы каждый больше не был одиноким, пустым и холодным на пути обучения.

Для лучшего ввода я выбираю Stack Overflow в качестве переднего края битвы, в конце концов, многие пожилые люди настоятельно рекомендуют его. В этой статье давайте рассмотрим, как изящно напечатать объект Java.

Неожиданно количество посещений по этому вопросу столь же велико, как и у Горного Алтая, с более чем 290 000 посещений, что невероятно! Это показывает, что многие, многие программисты были обеспокоены этой проблемой.

Давайте рассмотрим вопрос спрашивающего.

Спрашивающий определяет класс следующим образом:

public class Cmower {
    private String name;

    public Cmower(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Затем создал объект этого класса и попытался его распечатать:

Cmower cmower = new Cmower("沉默王二");
System.out.println(cmower);

Но на выходе получается не то, что он хочет:

com.cmower.java_demo.stackoverflow.printObject.Cmower@355da254

Кроме того, у него тоже была похожая проблема при печати массива:

Cmower [] cmowers = {new Cmower("沉默王二"), new Cmower("沉默王三")};
System.out.println(cmowers);

Результат:

[Lcom.cmower.java_demo.stackoverflow.printObject.Cmower;@4dc63996

Cmower@355da254и[LCmower;@4dc63996Что означает этот результат вывода? Как я могу напечатать имя класса Cmower? А как напечатать список (массив или коллекцию) объектов?

Если вы были обеспокоены этой проблемой или беспокоитесь, пожалуйста, следуйтеяДавай, давайте разберем этот вопрос рядом, рука об руку и найдем лучший ответ. Дуанг, Дуанг, Дуанг, сражайся с монстрами, чтобы продвинуться вперед!

01. Что случилось?

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

System.out.println(object);  // 调用 object.toString()

toString()Метод, определенный классом Object (надклассом всех объектов Java), возвращает непонятную строку:

1) Имя класса, состоящее из имени пакета и имени класса, напримерcom.Cmower;
2) разъем @;
3) Хэш-код в шестнадцатеричном формате.

Взгляните на исходный код этого метода:

public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

Массивы похожи на обычные объекты Java, с одним лишь отличием — отслеживание класса.getName()метод может подтвердить это.

If this class object represents a class of arrays, then the internal form of the name consists of the name of the element type preceded by one or more '[' characters representing the depth of the array nesting.

Общий смысл в том, что если это массив, то перед именем класса будет стоять одна или несколько английских скобок "[", обозначающих размерность массива (одномерный массив - одна "[", двумерный массив состоит из двух «[» »), за которыми следует начальный тип элемента.

Вот почему массивы объектов имеют префикс «[L». Есть ли ощущение внезапного осознания?

02. Пользовательский вывод

Если вы хотите вывести ожидаемые результаты при печати, вы должны переопределить его в пользовательском классе.toString()метод, см. пример.

public class Cmower {
    private String name;
    // 省略构造方法和 getter/setter

    @Override
    public String toString() {
        return name;
    }
}

Когда мы снова печатаем объект Cmower, вывод больше неcom.Cmower@355da254.

沉默王二

Но этот результат нас не устраивает, он немного навязчив и не может отображать тип объекта. Более элегантный подход таков:

public class Cmower {
    private String name;
    // 省略构造方法和 getter/setter

    @Override
    public String toString() {
        return getClass().getSimpleName() + "[name=" + name + "]";
    }
}

Снова распечатайте объект Cmower, и результат будет таким:

Cmower[name=沉默王二]

Эта форма не только красиво выглядит, но и дает полезную информацию при отладке. Однако иногда мы не хотим переписыватьtoString()Метод (хотите сохранить исходный формат печатиClassType@123121) и хотите распечатать информацию об объекте, то лучше всего определить новый метод, напримерtoMyString()метод.

03. Автоматический вывод

IDE (Eclipse или Intelj IDEA) обычно предоставляют выходной формат для переопределения полей класса.toString()метод.

@Override
public String toString() {
    return "Cmower{" +
            "name='" + name + '\'' +
            '}';
}

Кроме того, некоторые сторонние библиотеки классов с открытым исходным кодом также предоставляют такие функции, например:

1) ToStringBuilder от Apache Commons Lang.

Инструкции:

@Override
public String toString() {
    return ToStringBuilder.reflectionToString(this);
}

Выходной результат:

com.cmower.printObject.Cmower@355da254[name=沉默王二]

2) MoreObjects от Google Guava

Инструкции:

@Override
public String toString() {
    return MoreObjects.toStringHelper(this)
            .add("name", getName())
            .toString();
}

Выходной результат:

Cmower{name=沉默王二}

3) Ломбок@toStringАннотация (IDE необходимо сначала установить плагин Lombok)

Инструкции:

@ToString
public class Cmower {

    private String name;

    // 省略构造方法和 getter/setter
}

просто нужен один@toStringАннотация, не нужно переопределятьtoString()метод.

Выходной результат:

Cmower(name=沉默王二)

04. Распечатайте список объектов (массив или коллекцию)

Вышеупомянутый контент уже объяснил вопрос печати одного объекта, вы в порядке? Далее поговорим о печати списка объектов.

1) Массив

Arrays.toString()Вы можете конвертировать любой тип массива в строку, включая массивы примитивных типов и массивы справочного типа. Пример кода выглядит следующим образом.

Cmower[] cmowers = {new Cmower("沉默王二"), new Cmower("沉默王三")};
System.out.println(Arrays.toString(cmowers));

Выходной результат:

[Cmower{name='沉默王二'}, Cmower{name='沉默王三'}]

2) Коллекция

Для коллекций его можно распечатать напрямую, чтобы вывести ожидаемые результаты. Пример кода выглядит следующим образом.

List<Cmower> list = new ArrayList<>();
list.add(new Cmower("沉默王二"));
list.add(new Cmower("沉默王三"));
System.out.println(list);

Выходной результат:

[Cmower{name='沉默王二'}, Cmower{name='沉默王三'}]

05. Спасибо

Что ж, мои дорогие читатели, на этом все. Если вы можете продолжать читать технические статьи во время эпидемии, второй брат должен поставить вам большой палец вверх 👍.

Быть оригинальным не просто, если считаешь это полезным, не скупись на рукикаксила — потому что это будет самой сильной мотивацией для моего письма.