Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/393.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java字符串相等示例_Java_String - Fatal编程技术网

Java字符串相等示例

Java字符串相等示例,java,string,Java,String,事先很抱歉问了一个基本问题,但有人能解释一下原因吗: String s = "lo"; String str7 = "Hel" + s; String str8 = "He" + "llo"; System.out.println("str7 == str8 is " + (str7 == str8)); 输出为假。 我认为str7和str8都指向字符串池中的同一个对象,特别是因为字符串是不可变的 我错了吗? str7和str8是否都不在池中,而是在堆中?为什么? 您能给我提供一些字符串操作的

事先很抱歉问了一个基本问题,但有人能解释一下原因吗:

String s = "lo";
String str7 = "Hel" + s;
String str8 = "He" + "llo";
System.out.println("str7 == str8 is " + (str7 == str8));
输出为假。 我认为str7和str8都指向字符串池中的同一个对象,特别是因为字符串是不可变的

我错了吗? str7和str8是否都不在池中,而是在堆中?为什么?

您能给我提供一些字符串操作的例子吗?当结果确实是字符串池中的同一个不可变字符串时

附言:


输出true

str7
str8
都在池中,但它们不是相同的字符串。也就是说,它们是相同字符序列的不同版本

想想如果VM每次创建一个字符串时都必须扫描整个池,以查看是否已经存在另一个具有相同字符序列的字符串,那么会对性能造成多大的影响

在您的新示例中,您正在从相同的基础字符串构建
str8
str9
,因此编译器可以更容易地判断每个字符串的结果是相同的,并且可以在池中重复使用该项。

如果您调用,那么编译器将扫描
字符串
池,并按照您的预期执行。就是

String s = "lo";
String str7 = ("Hel" + s).intern();
String str8 = ("He" + "llo").intern();
System.out.println("str7 == str8 is " + (str7 == str8));
输出

str7 == str8 is true
导致这种行为的原因有两个

  • String
    是不可变的,因此使用
    +
    必须创建新的
    字符串
  • String
    连接通常通过
    StringBuilder
    实现,即
    new StringBuilder(“Hel”)。append.toString()
    new StringBuilder(“He”)。append(“llo”)。toString()
    StringBuilder
    不扫描
    字符串
    内部池

  • 对于所有文本都进入字符串池的池,您的理解是正确的

    在进行连接时会出现混淆。这里有两点需要注意

    1) 如果字符串在编译时解析,那么它将与字符串池同步并使用相同的文本。前

    String str7 = "Helllo";
    String str8 = "He" + "llo";
    
    请注意,两者都是纯文本。因此没有运行时转换等

    2) 如果字符串在运行时解析,则它在运行时解析为新字符串,并与任何其他字符串不同,除非使用.equals方法比较其内容

    String str7 = "Hel" + s;
    String str8 = "He" + "llo";
    System.out.println("str7 == str8 is " + (str7 == str8)); //false
    
    在本例中,带有(+)运算符的concat字符串,JVM返回
    新的StringBuilder(字符串…).toString()
    ,因为一个是纯文本,另一个是变量

    看这张照片

    如果只有一个操作数表达式为String类型,则在运行时对另一个操作数执行字符串转换(§5.1.11),以生成字符串

    评论中的问题:

    这是否意味着,如果字符串是文字串联的产物,那么结果在池中总是相同的字符串

    是的。请记住,串联指的是编译时解析表达式(也称为常量表达式),而不是运行时

    当我们将字符串文字与字符串对象连接起来时,得到的字符串总是一个通过StringBuilder在后台构建的新字符串对象

    是,返回了一个新字符串。附加的JVM链接证实了这一点

    String s = "lo";
    String str7 = "Hel" + s;
    String str8 = "He" + "llo";
    String str9 = "He" + "llo";
    
    s
    引用的对象是表示“lo”文本的字符串对象。它在字符串池中

    str8
    str9
    引用的对象是对常量表达式求值的结果。因此,它们在字符串池中。事实上,由于表达式的计算结果是“相同的”字符串,
    str8
    str9
    引用的是相同的实际
    string
    对象

    str7
    引用的对象是对非常量表达式求值的结果。因此,它不在字符串池中

    “Hel”+s
    在这里不是一个常量表达式的最终原因是
    s
    没有声明为
    final


    这里要记住的是,字符串对象仅在两种情况下分配到字符串池中:

  • 如果它们是计算常量表达式的结果,或
  • 如果它们是使用
    String.intern()
    方法显式生成的
  • 字符串文字是常量表达式的一个子实例

    有关常量表达式是什么的更详细解释,请参阅Java语言规范-(常量表达式)和(常量变量)


    任何在这些情况下不产生的字符串都不在字符串池中。

    @RajithPemabandu:但问题是关于底层表示的;使用
    equals
    是为了避免这些细节。str8==str9的原因与编译器优化有关:对不起,斯科特-我完全困惑和不知所措。“同一字符序列的不同版本”在池中的确切含义是什么?至于扫描整个池,我认为这正是拥有字符串池的目的;编译器平衡了查找匹配字符串(通常会失败)的成本和重复使用字符串的好处。您似乎了解“相同字符序列的不同版本”是什么这意味着可以对此进行争论:两个不同的字符串占据了内存中的不同位置,它们碰巧具有相同顺序的相同字符。这是不正确的<代码>str7
    不在字符串池中。它不是常量表达式的结果,也没有被显式插入。我知道intern()的含义,多亏了这个问题,为什么这两个字符串s7和s8指向同一位置的不同字符串-字符串pool@AndreyM.Stepanov我希望我的两个要点能澄清为什么。。。Stephen C解释了为什么s7和
    String s = "lo";
    String str7 = "Hel" + s;
    String str8 = "He" + "llo";
    String str9 = "He" + "llo";