在面试的时候,equals和== 的区别基本上是逃不过的问题,那么都是等于,equals和 ==究竟有什么区别呢?
首先看这样一段代码:
package Demo1; public class TestDemo2 { public static void main(String[] args) { String s1 = "hello"; String s2 = "hello"; String s3 = new String("hello"); String s4 = new String("hello"); int a=21; int b=21; System.out.println(s1==s2); System.out.println(s1==s3); System.out.println(s2==s3); System.out.println(s3==s4); System.out.println(s1.equals(s2)); System.out.println(s2.equals(s3)); System.out.println(s1.equals(s3)); System.out.println(s4.equals(s3)); } }输出的结果是什么呢?
我们都知道,在JVM(java虚拟机)中,内存被分为了堆内存跟栈内存。当我们通过new创建一个对象的时候,就会调用该对象的构造函数在堆内存中开辟空间并且将对象的值(内容)存储到堆内存中,与此同时在栈内存中会生成该对象对应的引用,而在后续调用的时候用的就是栈内存中的引用。 所以上面得代码在堆栈内存中的分配就是 这时候我们来看看上述代码的输出结果
true false false false true true true可以发现s1和s2和equals的结果输出都是true,而s1和s2对于s3的的结果为false而equals的结果是true, 参考上面的内存图可以看到s1和s2都指向了同一块堆内存区域,而s3和s4都是单独指向了一块新的内存区域,所以s1和s2引用的是同一对象的,而s3和s4都是分别引用的是另一个新的对象,只是对象的值一样。 这里涉及到一个字符串常量池的概念,大致意思就是通过=新建一个字符串的时候会先去常量池看看有没有这个值,如果有则直接将这个字符串的引用指向这块内存地址,如果没有则新建一个。而通过new的方式新建一个对象不管堆内存中是否有这个值,都会重新申请一块内存并进行引用。
所以equals和== 的区别总结: == 用于对象:比较的是变量(栈)内存中存放的对象的(堆)内存地址,用来判断两个对象的地址是否相同,即是否是指相同一个对象。比较的是真正意义上的指针操作。 == 用于基本数据类型:则比较值是否相同。基本数据类型不存储在堆内存中,成员变量的基本数据类型是存在方法区的常量池中,局部变量的基本数据类型是存在栈内存的常量池中 而equals则是用来比较的是两个对象的内容是否相等,并且equals不能应用于基本数据类型,强行写的话会报错
Cannot invoke equals(int) on the primitive type int
可以扫描二维码关注微信公众号阅读原文。
