繁体   English   中英

为什么没有调用A类中的toString?

[英]Why is toString in class A evoked even though it is not called?

public class Test {
    public static void main(String[] args) {
        Object a1 = new A();
        Object a2 = new Object();
        System.out.println(a1);
        System.out.println(a2);
    }
}

class A {
    int x;

    public String toString() {
        return "A's x is " + x;
    }
}

输出量

A的x是0

java.lang.Object@1edf1c96

打印a1时,将调用类A中的toString()方法,而无需显式调用它。 你能告诉我这是怎么发生的。

toString()println(Object)隐式调用。 显然,因为它需要显示String ,所以保证toString()返回所有对象的某种形式的String表示形式。

正如您可以在PrintStream.println(Object)的文档中阅读的那样:

public void println(Object x)

打印一个对象,然后终止该行。 此方法的行为就像先调用print(Object)然后调用 println()

参数:
x要打印的对象。

现在,如果我们看一下PrintStream.print(Object) ,我们将看到:

public void print(Object obj)

打印对象。 根据平台的默认字符编码, String.valueOf(Object)方法生成的字符串转换为字节,然后以write(int)方法的方式完全写入这些字节。

参数:
obj要打印的对象

现在您可以看到,内部调用了String.valueOf(object) ,其定义为:

public static String valueOf(Object obj)

返回Object参数的字符串表示形式。

参数:
obj一个对象。
返回值:
如果参数为null ,则字符串等于"null" ; 否则,返回obj.toString()的值。

因此,这意味着如果您编写如下内容:

System.out.println(foo);

您实际上已经写了相当于

System.out.print(foo);
System.out.println();

进一步扩展为:

System.out.print(String.valueOf(foo));
System.out.println();

扩展为:

if(foo == null) {
    System.out.print("null");
} else {
    System.out.print(foo.toString());
}
System.out.println();

或者说得更清楚些。 PrintStream的代码中,您将看到类似以下内容的内容:

public class PrintStream {

    // ...

    public void println(Object x) {
        this.print(x);
        this.println();
    }

    public void print(Object obj) {
        String result = String.valueOf(obj);
        // ... do something with result (print it to the stream)
    }

}

String您会发现类似以下内容:

public class String {

    // ...

    public static String valueOf (Object obj) {
        if(obj == null) {
            return "null";
        } else {
            return obj.toString();
        }
    }

}

在每个Object中都定义了toString()方法。 它的默认行为是返回该对象的字符串表示形式,例如"java.lang.Object@1edf1c96"

在您的A类中,您只是通过重新定义toString()方法而用新的行为替换了该行为(“重新定义”意味着使用相同的签名在子类中再次定义该方法)。

这称为Override

当您打印对象时, println()方法将盲目调用对象的toString()方法,而不知道(或关心)是否已重新定义该对象。

如果要将任何对象表示为字符串,则存在toString()方法。

toString()方法返回对象的字符串表示形式。

如果打印任何对象,则Java编译器会在内部调用该对象的toString()方法。 因此,重写toString()方法,返回所需的输出,它可以是对象的状态,等等。这取决于您的实现。

通过重写Object类的toString()方法,我们可以返回对象的值,因此无需编写太多代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM