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

Posted Redotz

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java中Object.toString()返回的字符串的含义相关的知识,希望对你有一定的参考价值。

toString()是Object类的一个公有方法,而所有类都继承自Object类。所以所有类即使不实现toString方法,也会存在从Object类继承来的toString。

类可以实现toString方法,在控制台中打印一个对象会自动调用对象类的toString方法,所以我们可以实现自己的toString方法在控制台中显示关于类的有用信息。

而八种基本数据类型没有toString()方法,只能使用相应的包装类才能使用toString()。

 

Object的toString方法返回的字符串很像是 对象名[email protected]+对象内存地址,但事实并不是这样。

 

这里写了两段测试代码。

第一段,在list中存储对象的toString返回的字符串。

第二段,在list中存储对象本身。

两段代码都会尝试找到list中的重复元素,并打印出它们。

public static void list_obj_toString(int size) {
        List<Object> list = new ArrayList<>();
        int repeated = 0;
        for (int i = 0; i < size; i++) {
            Object obj = new Object();
            if (list.contains(obj.toString())) {
                System.out.println("Object " + obj.toString() + " has repeated!");
                repeated++;
            } else {
                list.add(obj.toString());
            }
        }
        System.out.println("Total Object.toString():" + size);
        System.out.println("Repeated Object.toString():" + repeated);
    }
public static void list_obj(int size) {
        List<Object> list = new ArrayList<>();
        int repeated = 0;
        for (int i = 0; i < size; i++) {
            Object obj = new Object();
            if (list.contains(obj)) {
                System.out.println("Object " + obj.toString() + " has repeated!");
                repeated++;
            } else {
                list.add(obj);
            }
        }
        System.out.println("Total Object:" + size);
        System.out.println("Repeated Object:" + repeated);
    }
    public static void main(String[] args) {
        list_obj_toString(2000000);
        list_obj(2000000);
    }

在main中分别调用这两个方法,会得到结果

Object.toString() [email protected] has repeated!
Object.toString() [email protected] has repeated!
... ...
Object.toString() [email protected] has repeated!
Object.toString() [email protected] has repeated!
Total Object.toString():200000
Repeated Object.toString():8
Total Object:200000
Repeated Object:0

 

从结果看,对象的toString出现了8次重复,而对象的句柄(另一种说法是“对象的引用”)当然一次重复都没有。

问题出在哪里了呢?至少我们现在可以肯定“对象名[email protected]+对象内存地址”这种说法肯定不对,因为内存地址肯定不会重复的。

 

先看看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方法在idea中以大约35%的CPU(intel i7 6500u)占用跑了大概三四分钟,而list_obj大概只用了不到五秒,可见,toString()方法在200000这个数量级上展现了它较低的时间效率,大概是由于大量字符串拼接导致的?希望以后有时间再做个测试。

PS:当list_obj_toString的参数size为100000时,出现了0次重复。而参数为200000时,出现了8次重复。可见java 10的hashCode()的哈希算法在这个数量级上会开始出现大量的哈希冲突。

以上是关于Java中Object.toString()返回的字符串的含义的主要内容,如果未能解决你的问题,请参考以下文章

Object.toString()方法返回16进制地址

Object.prototype.toString()

NullPointerException:无法调用“Object.toString()”,因为“javax.swing.JButton.getIcon()”的返回值为 null

JavaScript toString() 函数详解

JavaScript toString() 函数详解

Java中区别.toString() ,(String),valueOf()方法