1 public class EqualsTest {
2
3 public static void main(String[] args) {
4 String s1 = "abc";
5 String s2 = "abc";
6 String s3 = new String("abc");
7 String s4 = new String("abc");
8
9 /*
10 * 首先要明确:==比较的是对象引用,即内存中的地址;
11 * equals比较的是引用中的内容;
12 *
13 * 还要注意:equals这个方法是Object基类中的方法,初始的源码其实与==效果是一样的,所以如果后续没有覆盖这个方法,就算
14 * equals也是比较的地址引用而不是其中的内容。。而我们一般直接用的String字符串的比较,已经重写了equals方法是比较内容,
15 * 所以可以直接用。
16 */
17
18 System.out.println("s1==s2:"+(s1==s2));//结果为true
19 /*
20 * 分析:s1==s2返回为true,则说明s1与s2指向的同一个内存地址;
21 * 当字符串"abc"给创建的字符串引用赋值时,java会首先在常量池中查找是否已经有这个常量对象,如果有就直接把这个常量的地址给引用对象;
22 * 当"abc"第一次进入常量池,创建s1对象,并将是s1对象引用指向"abc"地址;当第二个常量"abc"进入时,虚拟机会首先查看常量池是否存在相同的
23 * 常量,此时发现已经存在,故直接将s2对象引用指向"abc"地址,所以s1其实与s2指向的是同一个地址;
24 */
25 System.out.println("s1 equals s2:"+s1.equals(s2));//结果为true
26 /*
27 * String类重写的equals方法,比较引用的内容,两个内容一样,返回true;
28 */
29 System.out.println("s1==s3:"+(s1==s3));//结果为false
30 /*
31 * String s1 = "abc";
32 * String s3 = new String("abc"); 这是String类提供的两种创建对象实例的方式,由于String对象是不可改变的对象,创建了就在内存中固定了,
33 * 所以第一种方式可以把"abc"看作常量,创建时会直接在方法区的常量池中,应该凡是以这种方式创建,都会首先在常量池中搜索是否已经存在这样的常量,如果有
34 * 直接将地址赋值给引用,所以这种方式不管是地址引用还是应用的内容都相同。
35 * 而第二种方式是new一个对象,并且直接初始化了,new String("abc")对象是直接放入堆内存开辟空间,并将引用地址赋值给引用变量s3,故可以说明凡是
36 * 经过new创建的对象引用都是新开辟的内存空间存放,比较引用肯定是fasle,如果两个引用地址中的内容相同,则equals为true;
37 */
38 System.out.println("s1 equals s3:"+s1.equals(s3));//结果为true
39 /*
40 * 比较的引用指向地址内容,相同
41 */
42 System.out.println("s3==s4:"+(s3==s4));//结果为false
43 /*
44 * 比较对象的引用,属于不同的引用,false
45 */
46 System.out.println("s3 equals s4:"+s3.equals(s4));//结果为true
47 /*
48 * 引用地址不同,但是引用指向的内容相同,true
49 */
50 }
51
52 }