A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 杜佳瑞 中级黑马   /  2012-8-5 02:28  /  2028 人查看  /  4 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

前两天还在想hashCode()这个方法什么时候调用呢,HashSet和HashMap这两个集合不用说,为保证元素唯一性肯定会调用HashCode,我疑惑的是其他集合创建对象会不会调用这个方法呢?今天一个小程序让我发现问题了。

import java.util.*;
class Test666
{
        public static void main(String[] args)
        {

                ArrayList al=new ArrayList();
                al.add(new Person("a1",11));
                al.add(new Person("a2",12));
                al.add(new Person("a2",12));
                al.add(new Person("a4",13));
                //System.out.println(al);我发现这句话打印不打印完全不一样,打印的话就会调用hashCode,不打印就不会调用,这也好理解toString(),这个方法会返回一个这样的值getClass().getName() + '@' + Integer.toHexString(hashCode())。这里面调用了。这说明ArrayList创建对象没有调用hashCode来分配地址,那内存总对象建立分配的地址是靠什么方法呢?

                Iterator it=al.iterator();
                while(it.hasNext())
                {
                        Person p=(Person)it.next();
                        System.out.println(p.getName()+"::"+p.getAge());
                }       
        }
}
class Person
{
        private String name;
        private int age;
        Person(String name,int age)
        {
                this.name=name;
                this.age=age;
        }
        public String getName()
        {
                return name;
        }
        public int getAge()
        {
                return age;
        }
        public int hashCode()
        {
                System.out.println(this.name+"...hashcode..."+this.name);
                System.out.println(name.hashCode()+age);
                return name.hashCode()+age;
        }               
}

评分

参与人数 1技术分 +1 收起 理由
杨志 + 1

查看全部评分

4 个回复

倒序浏览
本帖最后由 余明辉 于 2012-8-5 02:52 编辑

就你注释那句话,来说说我的理解吧
System.out.println(al);
相当于System.out.println(al.toString());
通过查阅API发现里面是这样描述的::返回该对象的字符串表示。通常,toString 方法会返回一个“以文本方式表示”此对象的字符串。
也就是说,打印出来的这个值,只是以文本方式描述的一个字符串而已,并不是真正的内存地址。只是一个字符意义上的地址。真正的内存分配还是有虚拟机内部执行的。
为了证实这个说法,我也查阅了相关资料,发现在Java中是不可能得到对象真正的内存地址的,因为Java中存放对象的堆是由虚拟机管理的,而我们是不能对虚拟机直接操作的。
希望我的回答可以帮到你,都半夜3点了,还在努力啊,早点休息吧,明天才有精力继续学习

评分

参与人数 1技术分 +1 收起 理由
杨志 + 1

查看全部评分

回复 使用道具 举报
余明辉 发表于 2012-8-5 02:50
就你注释那句话,来说说我的理解吧
System.out.println(al);
相当于System.out.println(al.toString());

呵呵 虽然还是不太理解 不过挺感谢你的
回复 使用道具 举报
杜佳瑞 发表于 2012-8-5 18:58
呵呵 虽然还是不太理解 不过挺感谢你的

这样和你解释吧,对象的分配工作,是由虚拟机执行的,至于怎么执行,我们不知道,它有自己的一套算法。
但是java是个面向对象的语言,每个对象总有一种描述形式吧,而在将java中,这种描述形式就是
getClass().getName() + '@' + Integer.toHexString(hashCode())来表示一个对象

再简单一点来说就是:虚拟机怎么创建对象的,我们不知道,但是我们要找这个对象的时候,就是通过哈希值去找
回复 使用道具 举报
谢谢 解决了
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马