Java 如何在println()内自动调用toString()

Java 如何在println()内自动调用toString(),java,constructor,Java,Constructor,我刚开始学习Java。我对constructor的了解是: 当对象初始化时,它将自动运行 构造函数的名称必须与类名相同 现在,下面是我开始感到困惑的地方 class Frog{ public String toString() { return "Hello"; } } public class App { public static void main(String[] args) { Frog frog1 = new Frog();

我刚开始学习Java。我对constructor的了解是:

  • 当对象初始化时,它将自动运行

  • 构造函数的名称必须与类名相同

  • 现在,下面是我开始感到困惑的地方

    class Frog{
    
       public String toString() {
          return "Hello";
       }
    }
    
    public class App {
    
       public static void main(String[] args) {
          Frog frog1 = new Frog();
          System.out.println(frog1);
       }
    }
    
    我的问题:
    既然
    publicstringtostring()
    不是构造函数,那么为什么在运行程序时它的行为会像构造函数一样呢。我认为只有在从
    应用程序
    类调用它时,它才能运行。

    简短回答:public
    frog1.toString()
    方法调用在系统.out.println(对象x)
    调用堆栈中使用

    但是怎么做呢?让我们一起找出答案:)

    查看
    PrintStream
    类(默认情况下,该实例用作
    System.out
    字段值)源代码及其
    println
    实现,该实现接受
    对象
    参数:

    public void println(Object x) {
        String s = String.valueOf(x);
        synchronized (this) {
            print(s);
            newLine();
        }
    }
    
    对象
    类型的参数的
    字符串
    值方法是:

    public static String valueOf(Object obj) {
        return (obj == null) ? "null" : obj.toString();
    }
    
    obj
    frog1
    在您的例子中,调用它的
    toString()
    方法,并返回控制台输出的
    “Hello”
    字符串实例)

    “toString”的行为不像构造函数;调用它的原因是
    main
    方法中的第二行:

      System.out.println(frog1);
    

    这将调用frog1上的
    toString

    公共字符串toString(){..}
    是类
    对象的方法,这里专门为
    Frog
    类重写。此方法返回对象值表示形式。它是一个方法而不是构造函数。请记住构造函数不能返回值

    有效的构造函数如下所示:

     public Frog(){}
    

    toString方法覆盖对象。toString

    public String toString() {
          return "Hello";
    }
    
    那么什么时候打电话

     System.out.println(frog1);
    

    调用PrintStream类print(obj)/println(obj)方法时,它是指向“hello”的对象,然后在内部调用write方法,参数为String。valueOf(obj)如下所示:

    public void print(Object obj) {
        write(String.valueOf(obj));
    } 
    
     /** 
     * Returns the string representation of the <code>Object</code> argument. 
     * 
     * @param   obj   an <code>Object</code>. 
     * @return  if the argument is <code>null</code>, then a string equal to 
     *          <code>"null"</code>; otherwise, the value of 
     *          <code>obj.toString()</code> is returned. 
     * @see     java.lang.Object#toString() 
     */ 
    public static String valueOf(Object obj) {
    return (obj == null) ? "null" : obj.toString();
    } 
    
    现在String.valueOf(obj)执行调用String方法的任务,如下所示:

    public void print(Object obj) {
        write(String.valueOf(obj));
    } 
    
     /** 
     * Returns the string representation of the <code>Object</code> argument. 
     * 
     * @param   obj   an <code>Object</code>. 
     * @return  if the argument is <code>null</code>, then a string equal to 
     *          <code>"null"</code>; otherwise, the value of 
     *          <code>obj.toString()</code> is returned. 
     * @see     java.lang.Object#toString() 
     */ 
    public static String valueOf(Object obj) {
    return (obj == null) ? "null" : obj.toString();
    } 
    

    toString
    的用法是为类提供一些有意义的表示。类似于对对象或类的描述可以放在
    toString
    方法中

    每当对象与任何
    字符串
    引用的操作一起使用时,如
    系统输出.print
    字符串s=“abcd”+frog1;“
    将返回
    toString
    的内容

    如果未重写
    toString
    ,它将返回对象类及其哈希代码。请检查

    根据你的代码

    • frogg1=new Frog();
      =>创建类型为
      Frog
      的对象
      frogg1
    • System.out.println(frog1);
      =>输出
      字符串
      表示法
      对象的
      frog1

    希望它能解释。

    我不确定您是否理解“像构造函数一样行为”的含义。当您执行
    new Frog()
    时,会调用Frog构造函数(默认构造函数,因为您还没有编写)。对
    .toString()
    的调用在对
    .println()的调用中自动完成
    ,它位于调用构造函数后的行中

    您可能会感到困惑,因为
    toString()
    是您声明的唯一方法。但是,您不知道类中自动存在隐式默认构造函数。如果您要键入它,它将如下所示:

    public Frog() {
        // default constructor does nothing
    }
    

    默认构造函数“表现得像一个构造函数”。
    toString()
    表现得像一个被另一个方法调用的方法(关键是
    println(Object o)
    肯定对象有一个
    toString()
    方法,因为它是类定义的一部分).

    完全正确。
    System.out.println(frog1)
    意味着调用
    toString()
    方法。当您执行类似于
    final String aString=“This is a”+frog1;
    的操作时,也会发生同样的情况,但我没有专门调用frog1.toString(),我只调用frog1。如果我在Frog类中有多个方法怎么办?这不意味着我必须指定要调用的方法吗?@Bernard不,只有名为toString()的方法才会被
    System.out.println(Object obj);
    当你放入
    frog1
    ,正如Cootri所解释的那样。尝试重命名你的toString()方法来测试()
    例如,查看
    System.out.println(frog1);
    的输出是如何变化的。因为您有一个方法
    public String toString()
    您基本上覆盖了默认对象的toString()方法。(所有类都自动扩展对象,允许使用一些默认对象方法,如toString()和getType()感谢@KevinCruijssen,老实说,作为一名java初学者,我无法真正理解Cootri发布的示例,直到KevinCruijssen用更简单的解释解释了它。同时也感谢所有帮助进行额外解释的bro。由于您没有为类Frog定义构造函数,java编译器添加了一个“默认构造函数”,由编译器自动生成。toString会自动为默认构造函数构造的frog1对象调用。请参阅?默认构造函数实际上会自动调用super();如果适用。