Java中String 的equals 和==详解

时间:2021-03-25 18:28:46

一、Java中数据存储区域包括:

1.寄存器:最快的存储区,由编译器根据需求进行分配,我们在程序中无法控制.
2. 栈:存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或者常量池中(字符串常量对象存放在常量池中。)
3. 堆:存放所有new出来的对象。
4. 静态域:存放静态成员(static定义的)
5. 常量池:存放字符串常量和基本类型常量(public static final)。
6. 非RAM存储:硬盘等永久存储空间

二、相关说明:

1.String类是不可变类,一个String对象所包含的字符串内容永远不会被改变。

2."equals()"判断两个字符串对象的内容是否相同

3."=="判断两个String实例的引用是否相同

4. 当调用 intern()时,如果池已经包含一个等于此 String 对象的字符串(用 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并返回此 String 对象的引用。它遵循以下规则:对于任意两个字符串 s 和 t,当且仅当 s.equals(t) 为 true 时,s.intern() == t.intern() 才为 true。 简而言之,intern() 返回一个字符串,内容与调用它的字符串的内容相同,但一定取自具有唯一字符串的池。

5.字面量定义的字符串会自动调用intern()
例子:
String b = "abc"等价于
String b = "abc".intern()

三、例子

例子A:
   String str1 = "java";
   String str2 = "java";
   System.out.print(str1==str2);
返回值:true

解说:

执行第一句:JVM首先在常量池中查找"java",之前常量池中没有"java", 所以,jvm找不到"java"。因此,JVM会在常量池创建"java",然后在栈上创建str1,指向它;

执行第二句:因为执行第一句的时候,JVM已经在常量池中创建了"java", 因此JVM直接在栈上创建str2变量,指向"java"。

所以,它们的引用相同,即str1 == str2。

例子B:
   String str1 = new String("java");
   String str2 = new String("java");
   System.out.print(str1==str2);
返回值:false

解说:

执行第一句:JVM在堆上创建一个"java"对象,在栈上创建str1变量,然后指向它;

执行第二句:在堆上再创建一个"java"对象,在栈上创建str2变量,指向它。

这两个"java”对象虽然内容一样,但内存地址不一样,属于不同的对象。因此,str1 != str2。

例子C:
   String str1 = "java";
   String str2 = "blog";
   String s = str1+str2;
   System.out.print(s=="javablog");
返回值:false

解说:

执行第一句:JVM会在常量池创建"java",然后在栈上创建str1,指向它;

执行第二句:JVM会在常量池创建"blog",然后在栈上创建str2,指向它;

执行第三句:JVM会在堆上创建一个对象,用于存储str1+str2的结果,然后在栈上创建s变量指向这个对象。

执行第四句:JVM在常量池中创建"javablog",所以,s 和 "javablog"的内存地址不一样。

因此 s  != "javablog"。

例子D:
    String str1 = "javablog";
    String str2 = "java"+"blog";
    System.out.println(str1 == str2);
    返回值:true

解说:

String str2 = "java"+"blog";    //在编译时被优化成String str2 = "javablog";

因此str1 == str2

例子E:
   String s1 = "java";
   String s2 = new String("java");
   System.out.print(s1.intern()==s2.intern());
返回值:true

解说:

intern() 返回一个字符串,内容与调用它的字符串的内容相同,但一定取自具有唯一字符串的池。

例子F:
   String str1 = "java";
   String str2 = new String("java");
   System.out.print(str1.equals(str2));
返回值:true

解说:

equals比较的是字符串内容