分析前基础了解:
一)JVM 把内存划分成两种: 一种是栈内存, 一种是堆内存.
在函数中定义的一些基本类型的变量和对象的引用变量 (变量名) 都在函数的栈内存中分配.
当在一段代码块定义一个变量时, Java 就在栈中为这个变量分配内存空间, 当超过变量的作用域后, Java 会自动释放掉为该变量所分配的内存空间, 该内存空间可以立即被另作他用.
堆内存用来存放由 new 创建的对象 (包括由基本类型包装起来的类: Integer,String,Double, 实际上每个基本类型都有他的包装类) 和数组.
二)Object 类中的 equals 方法: public boolean equals(Object obj) {return (this == obj);} // 可以看出 Object 类中 equals 方法是用 == 判断对象引用是否指向同一内存地址.
三)String 类很特殊 ,String 类对 equals 方法进行了重写, 如下: 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;} // 可以看出在 String 类中 equals 方法不仅可以用 == 判断对象的内存地址是否相等, 相等则返回 true. 如果前面的判断不成立, 接着判断括号内的对象上是否是 String 类型, 接着判断两个字符串对象的的长度是否相等, 最后判断内容是否相等, 如果相等则返回 true.
四)开始具体分析:
4.1 在基本数据类型中的比较 int num1 = 10;int num2 = 10;System.out.println(num1 == num2); //true//num1 和 num2 都是 int 型 它们的值都是 10, 因此使用 "==" 当然相等.
4.2 在引用数据类型中的比较String s1 = "hello";String s2 = "hello";System.out.println(s1 == s2); // trueSystem.out.println(s1.equals(s2)); // true
![](http://i2.51cto.com/images/blog/201809/01/c00e1eaaca2f6f2fe06c9643d522c1ef.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)
当执行 String s1 = "hello"; 这条语句时, 会在堆中的字符常量池里找 "chance" 这个字符串, 若没有找到, 则将 "hello" 这个字符串放入字符串常量池中. 而在栈中开辟一块名为 s1 的空间存放 "chance", 这块空间的引用. 当执行 String s2 = "hello"; 这条语句时, 会在堆中的字符串常量池里找 "chance" 这个字符串, 很显然, 可以找到, 于是便把字符常量池里 "chance" 这个字符串的引用地址赋给 s2, 因此 s1 与 s2 存放的都是堆中字符常量池中的同一个 "chance" 的引用, 接着 System.out.println(s1.equals(s2)); 这里的 equals 在 String 类中被重写过, 用来比较两个字符串的实际内容是否相等, 即每一个字符是否相等, 重写方法末尾会另做说明!!! 因为比较的是字符串内容, s1,s2 内容都是 chance 当然是相等的.
- (2) String ss1 = "aaa";
- String ss2 = new String("aaa");
- System.out.println(ss1 == ss2); //false
- System.out.println(ss1.equals(ss2)); // true
- ![](http://i2.51cto.com/images/blog/201809/01/b5d497d07116d56b43dd1d597d5f65b9.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)
ss2 是 new 出来的, 所以重新分配内存地址, 当用 == 判断时, 返回 false, 但是两个字符串的内容相同, 所以用 equals 方法时, 返回 true.
- (3)String sss1 = new String("aaa");String sss2 = new String("aaa");System.out.println(sss1 == sss2); //falseSystem.out.println(sss1.equals(sss2)); // true
- ![](http://i2.51cto.com/images/blog/201809/01/0ea48bf88aaf7a04b5c1a199be34fbf4.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)
sss1 和 sss2 都为 new 出来的对象, 各占有一块内存空间, 所以内存地址不同, 但是字符串内容相同.
(4) 非 String 类, 例如 StringBuffer 类 没有重写 equals 方法, 所以不比较内容.== 和 equals 都是比较的内存地址
StringBuffer stringBuffer = new StringBuffer("aaa");StringBuffer stringBuffer2 = new StringBuffer("aaa");System.out.println(stringBuffer == stringBuffer2); // falseSystem.out.println(stringBuffer.equals(stringBuffer2)); // false
来源: http://www.bubuko.com/infodetail-2750843.html