黑马程序员技术交流社区

标题: 明白了,可问题又来了 [打印本页]

作者: 杜佳瑞    时间: 2012-8-5 02:28
标题: 明白了,可问题又来了
前两天还在想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;
        }               
}

作者: 余明辉    时间: 2012-8-5 02:50
本帖最后由 余明辉 于 2012-8-5 02:52 编辑

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

呵呵 虽然还是不太理解 不过挺感谢你的
作者: 余明辉    时间: 2012-8-5 19:52
杜佳瑞 发表于 2012-8-5 18:58
呵呵 虽然还是不太理解 不过挺感谢你的

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

再简单一点来说就是:虚拟机怎么创建对象的,我们不知道,但是我们要找这个对象的时候,就是通过哈希值去找
作者: 杜佳瑞    时间: 2012-8-5 21:51
谢谢 解决了





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2