`

基于hashcode的内存分配与==的比较问题

 
阅读更多
public class   student
{ 
    private   String   name; 
    private   int   age; 
    public   student(String   name,int   age)
    { 
              this.name=name; 
              this.age=age; 
    } 
    public   int   hashCode()
    { 
              
              //这里随便写,只要是按属性生成的即可 
              return   7*name.hashCode()+13*age; 

    } 
}
public   class   testHashcode
	{ 
        public   static   void   main(String[]   args)
        { 
                  student   stu1=new   student( "aa ",12); 
                  student   stu2=new   student( "aa ",12); 

                  //打印两个对象的内存地址 
                  System.out.println(stu1); 
                  System.out.println(stu2); 

                  //打印两个对象内存地址的比较 
                  System.out.println(stu1==stu2); 
        } 
} 


先看这个程序!!
这个程序证明内存的地址分配时基于hashcode分配的!!
把这个程序分别放在同包和不同包 并且测试下重写hashcode和不重写的打印结果
看结果
不同包  不 重写hashcode 
test2.student@c17164
test2.student@1fb8ee3
false


同包  不重 写
test1.student@c17164
test1.student@1fb8ee3
false

同包 重写hashcode
test1.student@a489c
test1.student@a489c
false

可以看出  重写时  因为student设置的属性值都是一样的!所以返回的hashcode值也是相同的!所以返回的内存地址也是相同的!!
但我们还很怀疑!
那看下面的程序
public   int   hashCode()
    { 
              
              //这里随便写,只要是按属性生成的即可 
              return   7*name.hashCode()+13*age+1; 

    } 


改下 hashcode的返回数据
结果是什么呢??
同包 重写 hashcode 但在原有基础的hashcode +1
test1.student@a489d
test1.student@a489d
false

现在相信了吧!内存地址也比之前增加了1个单位!!
但这时两个对象还是不想同!!
所以==比较的不仅仅是内存地址啊!!

开始我是这么想的
再看下面
Object.toString的实现方法是  
  getClass().getName()   +   '@'   +   Integer.toHexString(hashCode())  
  实际上是Object的hashCode方法返回对象的地址。所以在需要得到内存地址的类到Object之间如果没有类对hashCode进行覆盖(override),就可以通过该方法得到对象的内存地址。反之就无法通过此方法得到内存地址。  
  我觉得应该可以通过某个函数来得到对象或变量的内存地址,但我们不能通过该地址来操作它所存储的内容。  
也就是说 你打印的话 就是根据 hashcode打印!!打印的是Object.toString()
所以上面的结果就得出了打印结果相同!!
但其实 这时打印的不是内存地址了!!!
接着
System.out.println(Integer.toHexString( System.identityHashCode(stu1)));  
 System.out.println( Integer.toHexString(System.identityHashCode(stu2)));

打印出来的是hashcode的16进制字符串
http://lz12366.iteye.com/admin/blogs/639969
这个介绍了hashcode的计算方法!!
文章讨论到了最后
看了很多人写的文章:还有think in java 中
都写到 System.out.println(Object);得到的是内存地址!!
前提是没有重写hashcode!!

分享到:
评论

相关推荐

    java内存对象分配过程研究

    本文将基于Java虚拟机(JVM)的内存模型,详细探讨对象在Java中的内存分配过程。 #### 二、Java虚拟机内存区域 Java虚拟机(JVM)是Java程序运行的基础平台,其内部有一套完整的内存管理机制。根据JVM规范,JVM的内存...

    深入HashCode方法

    这个索引是由对象的HashCode与0x7FFFFFFF进行与操作后再对容器长度取模得出的。这种方法确保了即使是负数的HashCode也能转化为正整数索引,从而适应数组的索引需求。 在存储过程中,对象直接放入对应索引位置,查询...

    java内存泄露总结

    在这个例子中,`Person`对象`p3`的属性`age`被修改后,其`hashCode`值也随之改变,导致基于`hashCode`实现的`HashSet`无法通过原对象找到对应的条目,从而无法正确移除对象。解决办法是在`Person`类中重写`equals`...

    Java 17道面试题和答案.docx

    - 通过`new String()`创建的`String`对象会在堆上分配内存,每次都会创建一个新的对象。 - `String`类重写了`equals()`和`hashCode()`方法,以支持内容比较和哈希操作。 5. **类的`equals()`方法**: - 自定义类...

    有关jave基本类的学习小结

    在比较对象时,如果需要基于对象的属性进行判断,而非内存位置,应该在子类中覆盖`equals()`方法并同时重写`hashCode()`方法以保持一致性,这通常遵循 equals 和 hashCode 的合同规则。同时,需要注意的是,当比较...

    Java面试题 .docx

    19. **内存分配与内存泄漏**: - 使用`sun.misc.Unsafe`或`ByteBuffer`可以分配大内存,但需注意释放,否则可能导致内存泄漏。 20. **JVM配置和调优**: - 常见参数如-Xms、Xmx设置堆大小,-XX:NewRatio调整...

    软件构造心得(10):编写等价性判断时重写Hashcode的原因:理论与性能分析

    在软件开发中,特别是在使用基于哈希的集合类如HashSet或HashMap时,重写对象的`hashCode()`方法显得尤为重要。这是因为这些数据结构依赖于对象的`hashCode()`来快速定位和检索元素。`hashCode()`方法返回一个整数值...

    Java面试八股文十万字总结.docx

    - **逃逸分析技术**:判断对象的使用范围,优化内存分配。 - **元空间替代永久代的原因**:解决永久代的容量限制问题。 - **Stop The World机制**:暂停所有用户线程以执行GC。 - **OopMap与安全点**:用于确定对象...

    面试题 Java 基础总结了经常会被面试官问的问题

    - **动态性**:支持动态内存分配,适应变化的环境。 - **分布式**:通过RMI实现远程方法调用。 - **健壮性**:有强大的内存管理,避免内存泄漏。 - **高性能**:JIT即时编译器提升运行效率。 - **解释性**:...

    Android面试常见58题.pdf

    - 进程是操作系统分配资源的基本单位,每个进程有自己的独立内存空间。 - 线程是CPU调度的基本单位,共享进程的内存空间和资源,线程间的通信更高效。 6. **`final`、`finally`和`finalize`**: - `final`用于...

    java面试题目 想要的拿去吧

    #### 八、`String`对象的创建与内存分配 在Java中,使用直接赋值的方式创建`String`对象会将其存储在字符串常量池中,而使用`new`关键字创建的`String`对象则会被分配在堆上。 ```java String s1 = "xyz"; // 常量...

    面试BATTMD

    1. ==和equals()与hashCode()的区别:==比较的是对象的引用,而equals()用于比较对象的内容。hashCode()是基于对象内容计算的哈希值,用于对象的快速定位。 2. 数据类型:int占4字节,char占2字节,long占8字节。 3....

    Java最常见的面试题208道.docx

    2. ==和equals(): `==`比较基本数据类型的值,对象引用时比较内存地址;equals()是对象的方法,用于比较对象内容。 3. hashcode()和equals():当两个对象equals()返回true时,hashcode()通常也应该相同,以满足哈希...

    面试相关问题

    内存分配 在Java中,内存主要分为栈内存(Stack)和堆内存(Heap)。 - **栈内存**:主要用于存储局部变量、方法调用过程中的临时数据等。 - **堆内存**:用于存储对象实例,通过关键字`new`创建的对象会分配在此。...

    Java 最常见的面试题(208道).pdf

    进程是系统分配资源的基本单位,每个进程有自己的独立内存空间。 14. **线程状态**:Java线程有新建、就绪、运行、阻塞和死亡五种状态。 15. **多线程同步**:synchronized、volatile、Lock(如ReentrantLock)等...

    java开发常用技术.docx

    - **==**:比较对象的引用,即内存地址是否相同。 - **equals**:默认行为与==相同,但可被重写以比较对象内容。 13. **HashCode和Equals** - **HashCode**:返回对象的散列码,用于哈希表(如HashMap)中的快速...

    Microsoft.Net常见问题集锦

    在 .Net 平台上,GC 的存在极大地简化了程序员的工作,避免了手动释放内存导致的内存泄漏等问题。通过定期检查托管堆上的对象,当发现某个对象不再被引用时,GC 会自动将其标记为垃圾并回收其占用的内存。 #### ...

Global site tag (gtag.js) - Google Analytics