Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/320.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 x = new String("xyz"); String y = "abc"; x = x + y; 我访问过很多网站,有人说这行代码创建了3个对象,有人说它创建了4个对象。我只是想知道在执行这行代码之后创建了多少个对象。新字符串(“xyz”)当然会创建一个新实例。“abc”和“xyz”存储在类常量池中,x=x+y在引擎盖下创建一个StringBuilder,从而创建一个新字符串,因此这里的字符串计数为4 编译器可能会用常量(“xyzabc”)

以下代码创建了多少个字符串对象

String x = new String("xyz");
String y = "abc";
x = x + y;
我访问过很多网站,有人说这行代码创建了3个对象,有人说它创建了4个对象。我只是想知道在执行这行代码之后创建了多少个对象。

新字符串(“xyz”)
当然会创建一个新实例。
“abc”
“xyz”
存储在类常量池中,
x=x+y
在引擎盖下创建一个
StringBuilder
,从而创建一个
新字符串
,因此这里的字符串计数为4



编译器可能会用常量(
“xyzabc”
)替换
x+y
),但是。

在运行结束时,将有四个
字符串
对象:

  • 与插入的
    “xyz”
    文本相对应的
    字符串
  • 其副本由
    新字符串(“xyz”)
  • 一个
    字符串
    ,对应于实习的
    “abc”
    文本
  • 对应于串联的
    “xyz”+“abc”

  • 真正的问题是将这些对象的一部分或全部归因于您的程序。可以合理地说,代码创建的
    String
    s只有两个或四个。即使总共有四个
    String
    对象,对象1和3也不一定是由代码创建的,因为它们是常量池,因此它们是在代码的直接控制之外创建的。

    如果要测试实例,请运行此代码段并查看输出:

    import static java.lang.System.identityHashCode;
    
    public class Program {
        public static void main(String... args) {
            String x = new String("xyz");
            String y = "abc";
            String z = x + y;
    
            System.out.printf("x: %d | %d\n", identityHashCode(x), identityHashCode(x.intern()));
            System.out.printf("y: %d | %d\n", identityHashCode(y), identityHashCode(y.intern()));
            System.out.printf("z: %d | %d\n", identityHashCode(z), identityHashCode(z.intern()));
        }
    }
    

    我使用jdk1.7.0_67获得以下输出:

    x:414853995 | 1719175803
    y:1405489012 | 1405489012
    z:1881191331 | 1881191331

    总共有4个
    String
    实例…

    我会说4,因为:

    • +1
    • +1
    • +2
    以下是方法:

    String x = new String("xyz"); // 2 objects created: the variable and the constant
    String y = "abc"; // 1 object created: the variable
    x = x + y; // 1 object created: the one by the StringBuilder class
    

    答案是4

    由于您使用了
    new
    关键字,Java将在普通(非池)内存中创建一个新的字符串对象,
    x
    将引用它。除此之外,文本“xyz”将放在字符串池中,该字符串池也是另一个字符串对象

    因此,4个字符串对象是:

  • “xyz”(在非池内存中)
  • “xyz”(池内存中)
  • “abc”(池内存中)
  • “xyzabc”(在非池内存中)
  • 如果您的代码是这样的:

    String x = "xyz";
    String y = "abc";
    x = x + y;
    
    那么答案将是3

    注:字符串#4位于非池内存中,因为字符串文字和通过计算常量表达式生成的字符串(见JLS§15.28)是唯一隐式插入的字符串


    来源:SCJP Sun认证Java 6程序员(第6章第434页)

    这个答案是为了纠正一些其他答案所带来的误解:

    例如:

    不过,编译器可能会用常量(“xyzabc”)替换x+y。@Binkan Salaryman

    …和字符串对象4[对应于串联的字符串]也可以由编译器计算并转换为一个内部常量。@dasblinkenlight

    这是不正确的。声明如下:

    15.18.1.字符串连接运算符+

    字符串对象是新创建的(§12.5),除非表达式是常量表达式(§15.28)

    为了限定为常量表达式,表达式中的变量名称必须为:

    引用常量变量(§4.12.4)的简单名称(§6.5.6.1)

    其中,“常量变量”定义为:

    常量变量是使用常量表达式(§15.28)初始化的基元类型或字符串类型的最终变量

    在本例中,
    x
    y
    都不是
    final
    ,因此它们不是常量变量。即使它们是
    final
    y
    也不是常量变量,因为在初始化时使用了
    new
    操作符


    简而言之,Java编译器不允许将内部常量
    “xyzabc”
    用作串联表达式的结果

    如果我在末尾添加以下语句:

        System.out.println(x == "xyzabc");
    

    假设编译器符合Java语言规范,它将始终打印
    false

    答案是4

    String x = new String("xyz");//First Object
    
    String y = "abc";//Second Object
    
    x = x + y;//Third, fourth Object
    

    看看反编译类,您将看到所有内容:)答案应该是:

    • 两个字符串(
      “xyz”
      “abc”
      )只是对常量池中位置的引用,因此这些字符串不是由您的代码创建的
    • 直接创建一个字符串(
      新字符串(“xyz”)
    • 字符串连接由编译器优化,并更改为StringBuilder,以便间接创建最后一个字符串

      public java.lang.String method();
      descriptor: ()Ljava/lang/String;
      flags: ACC_PUBLIC
      Code:
        stack=3, locals=3, args_size=1
       0: new           #2                  // class java/lang/String
       3: dup
       4: ldc           #3                  // String xyz
       6: invokespecial #4                  // Method java/lang/String."<init>":(Ljava/lang/String;)V
       9: astore_1
      10: ldc           #5                  // String abc
      12: astore_2
      13: new           #6                  // class java/lang/StringBuilder
      16: dup
      17: invokespecial #7                  // Method java/lang/StringBuilder."<init>":()V
      20: aload_1
      21: invokevirtual #8                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      24: aload_2
      25: invokevirtual #8                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      28: invokevirtual #9                  // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      31: astore_1
      32: aload_1
      33: areturn
      
      public java.lang.String方法();
      描述符:()Ljava/lang/String;
      旗帜:ACC_PUBLIC
      代码:
      堆栈=3,局部变量=3,参数大小=1
      0:new#2//class java/lang/String
      3:dup
      4:ldc#3//字符串xyz
      6:invokespecial#4//方法java/lang/String.“:(Ljava/lang/String;)V
      9:astore_1
      10:ldc#5//字符串abc
      12:astore_2
      13:new#6//class java/lang/StringBuilder
      16:dup
      17:invokespecial#7//方法java/lang/StringBuilder。”“:()V
      20:aload_1
      21:invokevirtual#8//方法java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      24:aload_2
      25:invokevirtual#8//方法java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      28:invokevirtual#9//方法java/lang/StringBuilder.toString:()Ljava/lang/String;
      31:astore_1
      32:alo
      
      public static void main(java.lang.String[]);
          flags: ACC_PUBLIC, ACC_STATIC
          Code:
            stack=3, locals=3, args_size=1
               0: new           #16                 // class java/lang/String
               3: dup
               4: ldc           #18                 // String xyz
               6: invokespecial #20                 // Method java/lang/String."<init>":(Ljava/lang/String;)V
               9: astore_1
              10: ldc           #23                 // String abc
              12: astore_2
              13: new           #25                 // class java/lang/StringBuilder
              16: dup
              17: aload_1
              18: invokestatic  #27                 // Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
              21: invokespecial #31                 // Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V
              24: aload_2
              25: invokevirtual #32                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/St
      ringBuilder;
              28: invokevirtual #36                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
              31: astore_1
              32: return
            LineNumberTable:
              line 6: 0
              line 7: 10
              line 8: 13
              line 9: 32
            LocalVariableTable:
              Start  Length  Slot  Name   Signature
                     0      33     0  args   [Ljava/lang/String;
                    10      23     1     x   Ljava/lang/String;
                    13      20     2     y   Ljava/lang/String;
      }
      
      At `0: new` Creates a new String Object 
      At `3:dup` ; make an extra reference to the new instance
      
          At `4:ldc #18` as seen literal "xyz" has been placed in the pool (one string Object) 
      At `6: invokespecial;` ; now call an instance initialization method with parameter and creates a object in nonpool memory.
      At `9: astore_1` Stores the above reference in local variable 1(i.e x)
      
      At `10:ldc #23` as seen literal "abc" has been placed in the pool (third string ) 
      
          At `12: astore_2` Stores the above reference in local variable (i.e y)
      
          28: invokevirtual #36 // Method java/lang/StringBuilder.toString:
      ()Ljava/lang/String;;(fourth String Object is Created)
      
      Line 1:String x = new String("xyz");
      Line 2:String y = "abc";
      Line 3:x = x + y;