【问题标题】:How this print statement works? [duplicate]这个打印语句是如何工作的? [复制]
【发布时间】:2025-11-25 16:35:01
【问题描述】:
interface TestA {
    String toString();
}

public class Test {
    public static void main(String args[]) {
        System.out.println(new TestA() {
            public String toString() {
                return "test";
            }
        });
    }
}

这将打印 test 作为输出。

  1. 谁能解释一下这是如何工作的?
  2. 当我将方法名称toString()更改为printString时,会打印 只是一个内存地址。解释它是如何工作的。

【问题讨论】:

  • TestA 是一个对象,它覆盖了toString 方法(来自Object),该方法由PrintStream 使用(PrintStream 调用对象的toString 方法)。 toString 的默认实现打印对象 hashcode

标签: java


【解决方案1】:

代码:

new TestA() {
    public String toString() {
        return "test";
    }
}

是一个匿名类,可以将其视为一种即时类定义和实例化。这个类定义实现了一个toString() 方法,它恰好返回字符串test。这个匿名类,当传递给System.out.println 时,会导致test 被打印出来。

如果你把TestA#toString改成TestA#printString,那么toString的实现就没有了,Java的默认行为就是打印hashcode。

【讨论】:

    【解决方案2】:

    Object 类定义了一个方法toString(),它返回对象的“字符串表示”。基方法返回类名和哈希码。

    覆盖toString() 方法并返回更好的表示通常是个好主意。

    Java 中有很多东西会调用对象的toString() 方法。 System.out.println() 就是其中之一。另一个常见的是+ 运算符,用于连接字符串(如"hello " + myObj)。

    在您的第一个示例中,您正在创建TestA 接口的匿名内部类 实例,并覆盖toString()。这意味着System.out.println() 打印您定义的"test" 字符串。

    如果你重命名方法,现在你只得到toString()的默认Object实现,并得到“内存地址”版本。

    【讨论】:

      【解决方案3】:

      Object 是 Java 中所有类的超类,它有一个方法 toString() 打印对象引用。
      如果您打印任何对象,java 编译器会在内部调用该对象的 toString() 方法。
      在这里,您正在打印new TestA(),因此它在内部调用toString 方法,您已将其覆盖以打印test

      但是当您更改方法的名称时,它会调用Object 类的toString 实现。

      【讨论】: