java中的==与equals

class Test
{
public int hashCode()
{
return 20;
}
}
class Demo
{
public static void main(String[] args)
{

Test t1=new Test();
Test t2=new Test();
System.out.println(t1.hashCode()+"\t"+t1+"\t"+t1.toString());
System.out.println(t2.hashCode()+"\t"+t2+"\t"+t2.toString());

//toString()-->getClass().getName() + '@' + Integer.toHexString(hashCode())

System.out.println(t1==t2);//false 比较的是t1和t2指向的对象的首地址
System.out.println(t1.equals(t2));//false 同上
}
}

明明复写了Object中的hashCode(),为什么还是false?对象的首地址和哈希值不同?
详细说明下,不要说废话..
麻烦剖析下t1==t2;JVM到底是怎么执行的?能否一步一步详细说明下?
感谢..

这是Object类的boolean的equals()方法源代码:
public boolean equals(Object obj) {
return (this == obj);
}

也就是说你的Test类没有覆盖equals()方法,也就是说
t1 == t2 与 t1.equals(t2) 实际上是一样的。

确实Object类的hashCode()方法实现确实“借助”了对象的内存地址。
但是hashCode的中文翻译是哈希码或散列值,与内存地址没有关系。

也就是说当两个对象进行 == 运算时,Java并不会调用hashCode方法,
所以你覆盖hashCode 对于 == 运算 不会有任何影响。追问

麻烦说下,当比较t1==t2时,JVM内部是怎么执行的?(这点迷惑)
能不能详细说明下?

追答

当运行 == 运算时,确实比较的是两个对象的内存地址,但不是调用hashCode方法。

温馨提示:答案为网友推荐,仅供参考
第1个回答  2013-01-25
==判断地址的,这是2个对象,当然不同了。
首地址和hashcode没什么关系。
hashcode和对象内容有关系。
你重写了hashCode,没有重写equals,所以还是false。Object的equals还是比较地址内容的。
实际上就等于==。

在有的类中在判断equals的时候,会先判断hashcode。如果hashcode相等再判断内容是否相等。
如果hashcode不同,直接返回false。
不知道你理解了没有。追问

我初学哈,
equals在object中
public boolean equals(Object obj) {
return (this == obj); //如果不重写 JVM 内部怎么执行的?
} //是不是调用this.toString()和obj.toString()然后去比较?

追答

如果不重写,jvm直接就比较内存地址,是不是一个对象。
你可以理解成是toString,因为对于没有重写toString方法的类,toString输出的是地址信息。
但是实际上不会这么做。不会调用toString方法,toString有调用取地址的方法,因为这样不是多余吗?直接调用取地址的方法比较就可以了。

追问

我现在明白对象在内存地址和对象的hashCode()是两个概念- -,
学过数据结构,哈希表,处理冲突- - 太浅了
呵呵,我是在想 如果在调用toString()
相当于
getClass().getName() + '@' + Integer.toHexString(hashCode())

这里面的hashCode()是被我复写的- -

比较的是内存地址....

追答

Object中的hashcode是本地方法,是调用C++的函数实现的。
如果有c++基础,你可以看下源码,现在这个源码读开放了。
不过也很麻烦啊,方法调来调去的,也不是很好读。

追问

谢谢了 - - 初学java

第2个回答  2013-01-25
要想相等 覆盖
public boolean equals(Object o){ }方法。

hashCode()的返回值和equals()的关系如下:
如果x.equals(y)返回“true”,那么x和y的hashCode()必须相等。
如果x.equals(y)返回“false”,那么x和y的hashCode()有可能相等,也有可能不等。

好好去理解下API文档。
第3个回答  2013-01-25
Test 中增加 如下代码:
@Override
public boolean equals(Object obj) {

if(null==obj)
{
return false;
}

if(this.hashCode()==obj.hashCode())
{
return true;
}

return false;
}
参考资料《thinking in java》好好看书啊。
第4个回答  2013-01-25
简单不废话,你没有重写equals方法,调用的实际是Object类中的equals方法,而Object类中的equals实现还是返回 this == obj。

总之,要达到你想要的比较效果,需要重写(覆盖)Object类中的equals方法追问

this==obj,jvm是怎么执行的,是不是先 求出this.toString()和obj.toString( )然后再比较?

追答

this == obj 就是比较的内存地址,一般只有对同一个对象的引用,才会有 o1 == o2

第5个回答  2013-01-25
很简单Object a == Object b表示他们在内存中的地址样
比如
public class User{
public String username;

public User(String username) {
this.username = username;

}

public boolean equals(User user) {
if (user == null) {
return false;
} else if (user == this) {
return true;
} else if (user incetanceof User) {
return user.username == this.username;
}
}

}

User u1 = new User("test");
User u2 = new User("test");

u1 == u2返回false

u1.equals(u2)返回true

equal继承自Object类,一般自己重写
反正记住,==是看地址,equals一般看值,简单类型都用==
纯手打 好累啊
给分分