当我们使用 + 运算符连接时创建的新字符串对象在哪里

Where is the new Object of String created when we concat using + operator

我知道这可能是非常基本的,而且可能非常简单,但我无法清楚地理解在这种情况下会发生什么,所以,就这样吧。

在下面的代码中:

String str1 = "Hello";
String str2 = "World";
String str3 = new String("HelloWorld");
String str4 = str1 + str2;

我知道str1和str2会分别创建一个对象"Hello"和"World"里面字符串常量池.对于 str3,在 之外创建了一个新对象 String Constant Pool,它指向 "HelloWorld" 创建的 inside 字符串常量池.

我的问题是,如果我连接 2 个或更多字符串(使用“+”或 concat() 方法)会发生什么情况?

是否会像 String str3 那样在池外部 创建一个新对象,或者 str4 会直接指向该对象"HelloWorld"字符串常量池

里面

PS : And IF it is the case similar as creation of new object outside the pool, then how does it happen without using the new keyword?

首先String s = new String("abs");它将创建两个对象,一个对象在池区,另一个在非池区,因为您使用的是new and 以及字符串文字作为参数。

String str1 = "Hello";
String str2 = "World";
String str3 = new String("HelloWorld");
String str4 = str1 + str2;

到目前为止你有五个字符串对象,四个在字符串常量池中,一个在堆中。所以你的 str4 是一个完全在字符串池中的新对象, 请同时检查以下代码,

 String str5="HelloWorld"; //This line will create one more String Constant Pool object because we are using the variable name as str5.
 String str6="HelloWorld";////This line will not create any object, this will refer the same object str5.

待测

System.out.println(str3==str4); //false
System.out.println(str4==str5);//false
System.out.println(str5==str6);//true

首先,这不是答案,这是您自己获得答案或情况说明的方式。
连接两个字符串总是创建字符串的新对象。
为了符合这件事,你可以做一件事,它是如何在内存堆和池中管理的。

1:转到 NetBeans:
2:这样写程序:

public class StringTest {
    public static void main(String[] args) {
        String str1 = "Hello";
        String str2 = "World";
        String str3 = new String("HelloWorld");
        String str4 = str1 + str2;
        String str5 = str1 + str2;
        String str6 = str1.concat(str2);

        String str7 = "HelloWorld";
        String str8 = "HelloWorld";

        System.out.println("");
    }
}

3: 在System.out.println("");这一行打个断点就可以了。
4: 现在调试这段代码。
5: 转到变量 window (Window->Debugging->Variables),它看起来像:

6:现在右键单击 str8 和 select 标记对象... 并为该对象添加一些标签,例如 Same Object .

现在您可以看到相同的标语行也出现在 str7 上,例如:

这表明两个引用 str7' andstr8` 都引用了同一个对象。

7:现在通过用不同的标记行标记它们来检查 str3-4-5-6 所有引用,例如:

要对该对象进行更多内部管理,只需通过右键单击变量 windows 中的变量名称查看 Show Refereances 选项,例如:

更新:
- 串联在堆中创建对象。
- 确保此语句 look 表示池不能包含具有相同值的多个字符串
- 这里 str7-8 是池中的引用对象,不同于第 7 点屏幕截图中描述的 str4-5-6
- 你也可以通过使用 == 运算符比较 str5str7 来确认它,如果它 returns true,连接在池中创建对象,因为 str7 引用池并且两者都引用同一个对象,但它将 returns false 因为两者不同。

        **str4 is stored in heap.**        
                String str1 = "Hello";
                String str2 = "World";
                String str3 = new String("HelloWorld");
                String str4 = str1 + str2;
                String str5="HelloWorld";
            if str4 is stored on string pool then str5 will point to same object where str4 is pointing.
            but this statement giving me false output-:
                **System.out.println(str4 == str5);**
            ***************output****************
            false

                 String str4 = (str1 + str2).intern();
                 String str5="HelloWorld";
                but if you are using  String.intern then this method will try to find a String with the same sequence of characters in the pool.
    **System.out.println(str4 == str5);**
    ***************output******************
    true


  [1]: https://i.stack.imgur.com/IjMhP.png

为了回答您的问题,在池外创建了 str4 对象。

这是我的解释:

    String s = "abc";
    String s1="xyz";

    String s3 = "abcxyz";
    String s2=s+s1;

    if(s2 == s3){
        System.out.println("true");
    }else{
        System.out.println("false");
    }

这将打印错误。这意味着 s2 没有引用 s3 创建的池对象。

在阅读我在这里的评论之前,请记住两点。

  1. 串联期间任何运行时操作的结果都会在堆区域中创建对象。
  2. intern() 方法从字符串常量池 (scp) 区域获取引用。

现在,

String s = "you";       // s in scp
String s1 = s + "me";   // "me" in scp and runtime operation here will put s1 in heap
String s2 = "youme";    // s2 in scp

为了确定我上面的观点,请看下面的代码。

System.out.println(s1 == s2);          // false , since s1 is in heap and s2 is in scp
System.out.println(s1.intern() == s2); // true , since s2 in scp and s1.intern() in scp

有没有像下面这样的。

String s3 = "you" + "me"; //operation is compile time now, s3 in scp

所以,

System.out.println(s3 == s2); // true, s3 in scp and s2 in scp

注意:String的"abc"值是编译时常量