在我们面试的时候,经常会被问到equals和==的区别是什么?
我们的回答往往就是==比较的是地址equals比较的是值,当然这句话不能说是错误的,因为对比他俩的区别确实是这样的,那他们的底层是怎样的呢?
我们先看一段代码
- public class Test {
- public static void main(String[] args) {
- int a = 1;
- Integer b = 1;
- Integer c = 1;
- String d = "1";
- String e = "1";
- String f = new String("1");
- System.out.println(a == b);//true
- System.out.println(a == c);//true
- System.out.println(b == c);//true
- System.out.println(Integer.parseInt(d) == a);//true
- System.out.println(Integer.parseInt(d) == b);//true
- System.out.println(e.equals(Integer.parseInt(d)));//false
- System.out.println(d == e);//true
- System.out.println(d == f);//false
- System.out.println(b.equals(a));//true
- System.out.println(b.equals(d));//false
- System.out.println(b.equals(f));//false
- System.out.println(d.equals(a));//false
- System.out.println(d.equals(b));//false
- System.out.println(d.equals(f));//true
- System.out.println("!!");
- }
- }
int和Integer的区别是什么?
int是基本类型Integer是引用类型,那么基本类型存在哪里呢?栈里?他可以存在堆里面吗?
答案是可以的,堆中存的是new出来的对象和成员变量,栈中存的是局部变量,成员变量和局部变量都可以分为基本类型和引用类型,所以只要他是成员变量,他就可以存在堆中
那么我们在看d和f有什么区别?
java提供了一个字符串常量池,这个常量池只会存在唯一的值,也就是说当e出现的时候,他会先找到d然后引用给e,若果没有的话会先创建一个再引用给e,那么他和f的区别是什么呢?他们的存储区域不同,new出来的对象是交给堆处理的,
那么回归正题那么d.equals(f)我们知道他是true,但是他不只是简单的对比了一下值,他是先比较了地址,地址不一样再比较的值,在String中 先是比较地址,地址一样就返回true,地址不一样再比较值,另外equals没有重写Object中的equals方法,比较的就是两个对象的地址(就是使用==来比较的)equals重写方法后要看是如何重写的(Object(地址)、Integer(值)、String(先地址后值、地址不同值相同返回true)、自定义类(可以自己定义))
说完equals我们在看==
a==b是比较的引用地址吗?
基本类型的存储方式是以值的形式存储的所以
==用于基本数据类型比较的是值(引用类型存的是地址,基本类型存的是值)
==用于包装类(引用类)比较的是对象地址