Java中Object.toString()返回的字符串的含義


toString()是Object類的一個公有方法,而所有類都繼承自Object類。所以所有類即使不實現toString方法,也會存在從Object類繼承來的toString。

類可以實現toString方法,在控制台中打印一個對象會自動調用對象類的toString方法,所以我們可以實現自己的toString方法在控制台中顯示關於類的有用信息。

而八種基本數據類型沒有toString()方法,只能使用相應的包裝類才能使用toString()。 

Object的toString方法返回的字符串很像是 對象名+@+對象內存地址,但事實並不是這樣。

 

這里寫了兩段測試代碼。

這兩個方法大致是相同的,都會創建指定數量的元素,然后放入容器。

在添加的過程中如果出現重復則會打印出提示,執行完后會打印出統計信息。

第一個方法在對象上調用toString,將得到的字符串放入List

 1     public static void list_obj_toString(int size) {
 2         List<String> list = new ArrayList<>();
 3         int repeated = 0;
 4         for (int i = 0; i < size; i++) {
 5             Object obj = new Object();
 6             if (list.contains(obj.toString())) {
 7                 System.out.println("Object " + obj.toString() + " has repeated!");
 8                 repeated++;
 9             } else {
10                 list.add(obj.toString());
11             }
12         }
13         System.out.println("Total Object.toString():" + size);
14         System.out.println("Repeated Object.toString():" + repeated);
15     }

第二個方法直接將對象本身放入List

 1     public static void list_obj(int size) {
 2         List<Object> list = new ArrayList<>();
 3         int repeated = 0;
 4         for (int i = 0; i < size; i++) {
 5             Object obj = new Object();
 6             if (list.contains(obj)) {
 7                 System.out.println("Object " + obj.toString() + " has repeated!");
 8                 repeated++;
 9             } else {
10                 list.add(obj);
11             }
12         }
13         System.out.println("Total Object:" + size);
14         System.out.println("Repeated Object:" + repeated);
15     }
    public static void main(String[] args) {
        list_obj_toString(2000000);
        list_obj(2000000);
    }

在main中分別調用這兩個方法,會得到結果

Object.toString() java.lang.Object@7f385cbe has repeated!
Object.toString() java.lang.Object@26cfdc15 has repeated!
... ...
Object.toString() java.lang.Object@f2eb847 has repeated!
Object.toString() java.lang.Object@6f99ed9f has repeated!
Total Object.toString():200000
Repeated Object.toString():8
Total Object:200000
Repeated Object:0

 

從結果看,對象的toString出現了8次重復,而對象的句柄(另一種說法是“對象的引用”)當然一次重復都沒有。

問題出在哪里了呢?至少我們現在可以肯定“對象名+@+對象內存地址”這種說法肯定不對,因為內存地址肯定不會重復的。

 

先看看Java API文檔,其中關於Object.toString()有這樣一段描述

The toString method for class Object returns a string consisting of the name of the class of which the object is an instance, the at-sign character `@', and the unsigned hexadecimal representation of the hash code of the object. In other words, this method returns a string equal to the value of:

 getClass().getName() + '@' + Integer.toHexString(hashCode())

那么,原因就找到了。@后面的是轉換為十六進制的對象的哈希值,所以當哈希沖突時,Object.toString()返回的字符串也不可避免地重復了。

以后再有人說toString會打印出對象的內存地址,你可以毫不猶豫地反駁他。

 

 

PS:當list_obj_toString的參數size為100000時,出現了0次重復。而參數為200000時,出現了8次重復。可見java 10的hashCode()的哈希算法在這個數量級上會開始出現大量的哈希沖突。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM