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虚拟机(JVM)的内存模型,详细探讨对象在Java中的内存分配过程。 #### 二、Java虚拟机内存区域 Java虚拟机(JVM)是Java程序运行的基础平台,其内部有一套完整的内存管理机制。根据JVM规范,JVM的内存...
这个索引是由对象的HashCode与0x7FFFFFFF进行与操作后再对容器长度取模得出的。这种方法确保了即使是负数的HashCode也能转化为正整数索引,从而适应数组的索引需求。 在存储过程中,对象直接放入对应索引位置,查询...
在这个例子中,`Person`对象`p3`的属性`age`被修改后,其`hashCode`值也随之改变,导致基于`hashCode`实现的`HashSet`无法通过原对象找到对应的条目,从而无法正确移除对象。解决办法是在`Person`类中重写`equals`...
- 通过`new String()`创建的`String`对象会在堆上分配内存,每次都会创建一个新的对象。 - `String`类重写了`equals()`和`hashCode()`方法,以支持内容比较和哈希操作。 5. **类的`equals()`方法**: - 自定义类...
在比较对象时,如果需要基于对象的属性进行判断,而非内存位置,应该在子类中覆盖`equals()`方法并同时重写`hashCode()`方法以保持一致性,这通常遵循 equals 和 hashCode 的合同规则。同时,需要注意的是,当比较...
19. **内存分配与内存泄漏**: - 使用`sun.misc.Unsafe`或`ByteBuffer`可以分配大内存,但需注意释放,否则可能导致内存泄漏。 20. **JVM配置和调优**: - 常见参数如-Xms、Xmx设置堆大小,-XX:NewRatio调整...
在软件开发中,特别是在使用基于哈希的集合类如HashSet或HashMap时,重写对象的`hashCode()`方法显得尤为重要。这是因为这些数据结构依赖于对象的`hashCode()`来快速定位和检索元素。`hashCode()`方法返回一个整数值...
- **逃逸分析技术**:判断对象的使用范围,优化内存分配。 - **元空间替代永久代的原因**:解决永久代的容量限制问题。 - **Stop The World机制**:暂停所有用户线程以执行GC。 - **OopMap与安全点**:用于确定对象...
- **动态性**:支持动态内存分配,适应变化的环境。 - **分布式**:通过RMI实现远程方法调用。 - **健壮性**:有强大的内存管理,避免内存泄漏。 - **高性能**:JIT即时编译器提升运行效率。 - **解释性**:...
- 进程是操作系统分配资源的基本单位,每个进程有自己的独立内存空间。 - 线程是CPU调度的基本单位,共享进程的内存空间和资源,线程间的通信更高效。 6. **`final`、`finally`和`finalize`**: - `final`用于...
#### 八、`String`对象的创建与内存分配 在Java中,使用直接赋值的方式创建`String`对象会将其存储在字符串常量池中,而使用`new`关键字创建的`String`对象则会被分配在堆上。 ```java String s1 = "xyz"; // 常量...
1. ==和equals()与hashCode()的区别:==比较的是对象的引用,而equals()用于比较对象的内容。hashCode()是基于对象内容计算的哈希值,用于对象的快速定位。 2. 数据类型:int占4字节,char占2字节,long占8字节。 3....
2. ==和equals(): `==`比较基本数据类型的值,对象引用时比较内存地址;equals()是对象的方法,用于比较对象内容。 3. hashcode()和equals():当两个对象equals()返回true时,hashcode()通常也应该相同,以满足哈希...
内存分配 在Java中,内存主要分为栈内存(Stack)和堆内存(Heap)。 - **栈内存**:主要用于存储局部变量、方法调用过程中的临时数据等。 - **堆内存**:用于存储对象实例,通过关键字`new`创建的对象会分配在此。...
进程是系统分配资源的基本单位,每个进程有自己的独立内存空间。 14. **线程状态**:Java线程有新建、就绪、运行、阻塞和死亡五种状态。 15. **多线程同步**:synchronized、volatile、Lock(如ReentrantLock)等...
- **==**:比较对象的引用,即内存地址是否相同。 - **equals**:默认行为与==相同,但可被重写以比较对象内容。 13. **HashCode和Equals** - **HashCode**:返回对象的散列码,用于哈希表(如HashMap)中的快速...
在 .Net 平台上,GC 的存在极大地简化了程序员的工作,避免了手动释放内存导致的内存泄漏等问题。通过定期检查托管堆上的对象,当发现某个对象不再被引用时,GC 会自动将其标记为垃圾并回收其占用的内存。 #### ...