java“==”异常行为

时间:2016-04-16 13:55:29

标签: java string

import java.lang.String;
public class Test {
    public static void main(String[] args) {
        String a1="ka";
        String a2="ka"; 
        System.out.println("a1==a2?  "+(a1==a2));
        String a3="k";
        String a4=new String("k");
        System.out.println("a3==a4?  "+(a3==a4))
        System.out.println("a3==a4?  "+(a3==a4.intern()));
        String a5="k";
        String a6=a4+"a";
        System.out.println("a1==a6?  "+(a1==a6));
    }
}

我得到的输出:

a1==a2?  true
a3==a4?  false
a3==a4?  true
a1==a6?  false
  • a1 === a2为true,因为第5行不会在字符串池区域中创建新的字符串文字。仅返回对先前创建的字符串的引用。
  • A3 A4 ==? false,因为a4将引用String对象而不是字符串池区域中字符串中的字符串。我的问题是如果a3引用字符串常量而不是String对象,它如何能够使用String类的方法?
  • a4.intern()将返回对字符串池中字符串的引用,该字符串恰好与a3相同
  • a6 = a4 +“a”将创建一个新字符串“ka”。但这实际上使用了StringBuilder类及其append方法。然后使用toString()将其转换为字符串。此进程是否将新创建的字符串“ka”存储在字符串池区域中?由于字符串已经在池中,因此第12行的代码应该返回对它的引用。所以a1 == a6应该是true.rt? 我是java的新手。请指导我在哪里犯错误?

1 个答案:

答案 0 :(得分:-1)

您正在错误地比较字符串(因为您实际上是在比较引用)

java中的String类在java.lang包中定义,它就是,而不是像int或boolean这样的原语。

String在Java中是不可变的和final的,在这种情况下,JVM使用String Pool来存储所有String对象。

创建String对象有哪些不同的方法?

我们可以使用new运算符创建String对象,就像任何普通的java类一样,或者我们可以使用双引号(文字赋值)来创建String对象。

致你的问题:

当我们使用双引号创建String时,JVM会在String池中查找是否存储具有相同值的任何其他String。如果找到,它只返回对该String对象的引用,否则它会创建一个具有给定值的新String对象并将其存储在String池中。

当我们使用new运算符时,JVM会创建String对象,但不会将其存储到String Pool中。我们可以使用intern()方法将String对象存储到String池中,或者如果池中已存在具有相等值的String,则返回引用。

所以当你这样做时

String s1 = "abc";
String s2 = "abc";

在StringPool中检查那些,因为s1已存在,s2将采用相同的引用,因此,s1 == s2为真。

但是当你这样做时:

String s3 = new String("abc");
String s4 = new String("abc"); 

您正在使用 new运算符,因此JVM没有检查堆中是否已存在字符串,它只会为s4分配 new 空间,所以是s3 == s4 ???当然没有。

请查看下面的图片,以获得更具说明性的示例。

enter image description here