java 地址那些事儿
先普及一下基础
假如现在如下一个类
class Person{
private String name;
public Person() {
}
}
实例化一个Person对象per
java中的对象都继承自object所以这个对象也拥有hashCode() toString() equals()等方法
除此之外还要知道一下:
System.out.println(per)实际print方法调用的是per对象的toString方法由于我并没有在Person类中重写此方法所以这里调用的是继承自Object类中的方法,下面贴一下此类中此方法的说明:
这里我们可以知道这里打印的其实此类名[email protected]+哈希码的16进制数
hashcode()有啥用?看说明:
这里我们可以知道这其实就是返回该对象的hashcode,在没有覆写Object类中hashcode方法那么默认是返回此对象的地址,若覆写了,则需要调用System.identityHashCode()方法来取得了。下面用例子来说明:
拓展:
如何判断两个对象是否相等?
在hashMap中,我们知道我们要用自定义的键去取得值,就必须保持代表键的对象是同一个,举一个小例子
import java.io.*;
import java.util.*;
class Person
{
private String name;
public Person(String name)
{
this.name=name;
}
}
public class Main{
public static void main(String args[]) throws Exception{ // 异常抛出,不处理
// 第1步、使用File类找到一个文件
Map<Person,String> map = new HashMap<Person,String>();
map.put(new Person("zhangsan"),"男人");
System.out.println(map.get(new Person("zhangsan")));
}
};
运行结果
这是怎么回事儿?
我将其中部分代码修改
Person per1= new Person("zhangsan");
Person per2 =new Person("zhangsan");
System.out.println(per1.hashCode());
System.out.println(per2.hashCode());
map.put(per1,"男人");
System.out.println(map.get(per2));
结果如图:
通过这个例子我们可以看出这其实是两个对象。
我们要让上面的两个匿名对象被认为是同一个对象则需要对Person类中的equal方法和hashcode方法进行重写如下代码:
public boolean equals(Object obj)
{
System.out.println(this);
System.out.println(obj);
System.out.println(System.identityHashCode(this));
System.out.println(System.identityHashCode(obj));
System.out.println(this.hashCode());
System.out.println(this.name.hashCode());
System.out.println(obj.hashCode());
if(this==obj)
{
return true;
}
if(!(obj instanceof Person))
{
return false;
}
Person p = (Person)obj;
if(this.name.equals(p.name))
return true;
else
return false;
}
public int hashCode()
{
return this.name.hashCode()*2;
}
运行结果:
从这里我们可以看出虽然两个对象地址不同,但通过重写equal和hashCode方法使得其被在认为是同一个对象,这里牵涉了许多hash表的知识不再赘述。
这里在执行第二个匿名对象时,会先判断这个匿名对象和上一个匿名对象的hash码是否一致,不一致则不会进入equal比较。
大家可以复制代码在IDE中调试来测试这两个方法是怎么调用的。
贴一个参考链接:https://www.cnblogs.com/skywang12345/p/3324958.html