大家在刷面试题的时候可能都刷到过equals和==之间的区别?简单来说答案就是:equals和 ==比较的都是地址,只不过许多类中都重写了equals方法,用来比较他们之间的值。接下来我们就详细看看,他们之间究竟有什么区别。
一、堆和栈的区别
举个例子说明一下,String a = new String(“123”);
1)、对象的引用放在栈中,上例中a放在栈中;
2)、八种基本数据类型放在栈中:byte,short,int,long,float,double,char,boolean;
3)、对象放在堆中,上例中new String(“123”)放在堆中。
因此基本数据类型用==号比较没任何问题。但是注意Integer,Float,Boolean…不属于基本数据类型,它们属于基本类型的包装类型。
二、几种常见类中的equals方法源码
// Object类
public boolean equals(Object obj) {
return (this == obj);
}
//Boolean类
public boolean equals(Object obj) {
if (obj instanceof Boolean) {
return value == ((Boolean)obj).booleanValue();
}
return false;
}
//Integer类
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
// String类
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
我们可以看到,除了基类Object中比较的是地址以外,其他几个类中重写equals方法后比较的都是值。这里只是随便列举了几个常见的类。
三、常量池
数字常量池存放的范围是-128~127。我们直接看代码
public static void main(String[] args) {
Integer start =128;
Integer end =128;
Integer start1 = 127;
Integer end1 = 127;
System.out.println(start == end);
System.out.println(start1 == end1);
}
运行结果为:false、true。
当Integer 初始化的范围在-128~127之间,是放在常量池中。但是当不在这个范围时,就会在堆中开辟一块空间来存放,所以这时候比较的地址是不同的,因此返回false。
四、实例分析
public static void main(String[] args) {
Map map = new HashMap();
map.put("ssk","0000");
String s = JSON.toJSONString(map);
Map map1 = JSONObject.parseObject(s, Map.class);
System.out.println("0000" == map1.get("ssk"));
System.out.println("0000" == map.get("ssk"));
}
返回结果为false,true;
首先“0000”是存在常量池中的,“0000”==map.get(“ssk”),因此map.get(“ssk”)也存在常量池中,“0000”==map1.get(“ssk”)返回false。可以判断出map1.get(“ssk”)是在堆内存中。