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的内存结构有堆内存跟栈内存。当我们通过new创建一个新对象的时候,就会调用该对象的构造函数在堆内存中开辟空间并且将对象的值(内容)存储到堆内存中,与此同时在栈内存中会生成该对象对应的引用,而在后续调用的时候用的就是栈内存中的引用。
所以上面得代码在堆栈内存中的分配就是
可以发现s1和s2和equals的结果输出都是true,而s1和s2对于s3的的结果为false而equals的结果是true, 参考上面的内存图可以看到s1和s2都指向了同一块堆内存区域,而s3和s4都是单独指向了一块新的内存区域,所以s1和s2引用的是同一对象的,而s3和s4都是分别引用的是另一个新的对象,只是对象的值一样。
这里涉及到一个字符串常量池的概念,大致意思就是通过=新建一个字符串的时候会先去常量池看看有没有这个值,如果有则直接将这个字符串的引用指向这块内存地址,如果没有则新建一个。而通过new的方式新建一个对象不管堆内存中是否有这个值,都会重新申请一块内存并进行引用。
这时候我们来看看上述代码的输出结果:
true false false false true true true true 复制代码
关于equals和==区别的总结:
== 用于引用类型:比较的是变量(栈)内存中存放的对象的(堆)内存地址,用来判断两个对象的地址是否相同,即是否是指相同一个对象。比较的是真正意义上的指针操作。
== 用于基本数据类型:则比较值是否相同。基本数据类型不存储在堆内存中,成员变量的基本数据类型是存在方法区的常量池中,局部变量的基本数据类型是存在栈内存的常量池中
equals是用来比较的是两个对象的内容是否相等,并且equals不能应用于基本数据类型,如果强行写的话会报错:
Cannot invoke equals(int) on the primitive type int 复制代码
本文对equals和==的区别做了一个简单的分析和总结,很多人对于这个也一直比较模糊,这个问题也基本是笔试面试的必问题了,所以必须弄清楚!