簡體   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