杰瑞科技汇

java 重写tostring

为什么需要重写 toString()

Object 类是所有 Java 类的父类,它提供了一个默认的 toString() 实现,当你直接打印一个对象时,System.out.println(myObject);,JVM 内部会调用 myObject.toString() 方法。

java 重写tostring-图1
(图片来源网络,侵删)

默认的 toString() 输出是什么?

它会返回一个看起来像这样的字符串: 类名@对象的哈希码(十六进制格式)

示例:

class Person {
    private String name;
    private int age;
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}
public class Main {
    public static void main(String[] args) {
        Person person = new Person("张三", 30);
        System.out.println(person); // 这里会自动调用 person.toString()
    }
}

输出结果:

Person@15db9742

这个输出 Person@15db9742 除了告诉我们对象的类型是 Person 之外,没有任何实际意义,我们无法从这个字符串中得知 person 对象的具体信息,比如它的名字和年龄。

重写 toString() 的主要目的就是提供一个有意义的、可读的字符串表示形式,方便我们进行调试、日志记录和开发。


如何手动重写 toString()

重写 toString() 非常简单,只需在你的类中添加一个符合以下签名的方法即可:

@Override
public String toString() {
    // 在这里返回一个描述该对象的字符串
    return "自定义的字符串内容";
}

重写上面的 Person 类:

class Person {
    private String name;
    private int age;
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
        return "Person[name=" + this.name + ", age=" + this.age + "]";
    }
}
public class Main {
    public static void main(String[] args) {
        Person person = new Person("张三", 30);
        System.out.println(person);
    }
}

输出结果:

Person[name=张三, age=30]

输出结果清晰明了,一眼就能看出这个 Person 对象的所有关键信息。


重写 toString() 的最佳实践

仅仅实现功能是不够的,遵循最佳实践能让你的代码更专业、更易维护。

1 使用 @Override 注解

这强烈推荐!@Override 注解告诉编译器:“我正在重写一个父类的方法”,如果你拼写错误,或者方法签名不匹配,编译器会立刻报错,从而避免了因拼写错误而创建了一个新的、与重写无关的方法。

2 格式要清晰、一致

一个好的 toString() 输出应该像一个固定的“模板”,方便开发者(包括未来的你)快速理解对象的结构。

  • 包含类名:通常以类名开头,Person[...]
  • 使用方括号 [] 或花括号 :这是一种约定俗成的做法,用来包裹内容。
  • 键值对:对于多个属性,使用 key=value 的形式,并用逗号 分隔。
    • Person[name=张三, age=30, city=北京]
  • 处理 null:如果对象的属性可能为 null,最好在 toString 中处理,避免输出 null 字符串,或者用特殊的标记(如 "null""<null>")表示。
    • Person[name=张三, address=null] 可以改为 Person[name=张三, address=<null>]

3 性能考虑

toString() 方法在调试日志中被频繁调用,所以性能也很重要,避免在 toString() 中进行耗时操作,

  • 访问网络
  • 读写文件
  • 复杂的数据库查询

toString() 应该是轻量级的。

4 包含所有重要信息

确保 toString() 的输出包含了所有对外部调试有用的信息,如果一个属性是 transient(不会被序列化)的,你可能需要考虑是否应该在 toString() 中包含它,这取决于你的设计意图。


使用 IDE 自动生成 toString()

手动编写虽然简单,但当类有很多属性时,会变得繁琐且容易出错,现代 IDE(如 IntelliJ IDEA 和 Eclipse)都提供了强大的自动生成功能。

以 IntelliJ IDEA 为例:

  1. 在类编辑器中,右键点击。
  2. 选择 Generate (或按快捷键 Alt + Insert)。
  3. 从弹出的菜单中选择 toString()
  4. IDE 会列出类的所有成员变量,你可以选择需要包含在 toString 输出中的变量。
  5. 点击 OK

IDEA 会自动生成一个格式良好、包含 @Override 注解的 toString() 方法。

自动生成的代码示例:

import java.util.Objects;
class Person {
    private String name;
    private int age;
    // 假设还有其他属性...
    private String city;
    // ... 构造方法和其他代码 ...
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", city='" + city + '\'' +
                '}';
    }
}

注意,现代 IDE(如 IDEA)在自动生成 toString() 时,通常会导入 java.util.Objects 类,并使用 Objects.toStringHelper() 或类似的内部机制来构建字符串,这比简单的字符串拼接更安全(能正确处理 null 值)。


进阶:使用 StringBuilder(手动优化)

如果你不想依赖 IDE,并且希望手动获得比字符串拼接()更好的性能,可以使用 StringBuilder

为什么用 StringBuilder 在循环或大量字符串拼接时,使用 会创建多个中间的 String 对象,因为 String 是不可变的,这会导致性能下降和内存浪费。StringBuilder 是可变的,它在一个缓冲区中构建字符串,效率更高。

示例:

class Person {
    private String name;
    private int age;
    private String city;
    // ... 构造方法 ...
    @Override
    public String toString() {
        return new StringBuilder()
                .append("Person{")
                .append("name='").append(name).append('\'')
                .append(", age=").append(age)
                .append(", city='").append(city).append('\'')
                .append('}')
                .toString();
    }
}

虽然对于简单的 toString 现代 Java 编译器对 的优化已经很好了,StringBuilder 的性能差异可能微乎其微,但养成使用 StringBuilder 的习惯对于复杂的字符串操作是非常有益的。

项目 说明
为什么重写 提供一个有意义的、可读的字符串表示,方便调试和日志记录。
如何重写 在类中定义 public String toString() 方法,并返回自定义字符串。
最佳实践 使用 @Override 注解;保持格式清晰一致(如 ClassName[key=value]);避免耗时操作。
自动生成 强烈推荐使用 IDE(如 IntelliJ IDEA)的自动生成功能,快速、准确、规范。
性能考虑 对于简单 toString, 拼接足够;对于复杂场景,优先考虑 StringBuilder

掌握 toString() 的重写是每个 Java 开发者的基本功,它能让你的代码在调试和日志输出时更加友好和专业。

分享:
扫描分享到社交APP
上一篇
下一篇