0

如果我写:

String s = new String("abc");

它创建一个类型String为“abc”的对象。如果我写:

String s = "abc";

这也创建了一个值为“abc”的对象。如何在不遇到 new 关键字的情况下创建对象。

另外,如果我写:

s.append("def");

它创建了另外两个字符串对象,即:

a. "abcdef"  
b. "def"

因此,在双引号内遇到任何内容时,都会创建一个新String对象。这是怎么发生的?

4

4 回答 4

8

它被称为 a String literal,并在JLS 3.10.5中指定:

字符串文字由用双引号括起来的零个或多个字符组成。字符可以用转义序列(第 3.10.6 节)表示 - 一个转义序列用于 U+0000 到 U+FFFF 范围内的字符,两个转义序列用于 U+010000 到范围内字符的 UTF-16 代理代码单元U+10FFFF。

于 2013-07-23T11:01:42.813 回答
6

"abc"是一个字符串字面量,由语言规范定义。

请参阅JLS 3.10.5

字符串文字由用双引号括起来的零个或多个字符组成。字符可以用转义序列(第 3.10.6 节)表示 - 一个转义序列用于 U+0000 到 U+FFFF 范围内的字符,两个转义序列用于 U+010000 到范围内字符的 UTF-16 代理代码单元U+10FFFF。

推荐阅读:

  1. 字符串对象和字符串字面量之间的区别
  2. Java 字符串池

另外,读字符串真的很特别

字符串文字存储在一个公共池中。这有助于为具有相同内容的字符串共享存储空间以节省存储空间。通过 new 运算符分配的字符串对象存储在堆中,相同内容不共享存储。

String s1 = "Hello";              // String literal
String s2 = "Hello";              // String literal
String s3 = s1;                   // same reference
String s4 = new String("Hello");  // String object
String s5 = new String("Hello");  // String object

在此处输入图像描述

s1 == s1;         // true, same pointer
s1 == s2;         // true, s1 and s1 share storage in common pool
s1 == s3;         // true, s3 is assigned same pointer as s1
s1.equals(s3);    // true, same contents
s1 == s4;         // false, different pointers
s1.equals(s4);    // true, same contents
s4 == s5;         // false, different pointers in heap
s4.equals(s5);    // true, same contents  
于 2013-07-23T11:01:17.233 回答
0

正如他们所有人都回答的那样,“abc”是一个字符串文字。对于您的第二部分问题,即为什么在执行语句后s.append("def")会创建两个对象,因为在 Java 中字符串是不可变的。

于 2013-07-23T11:11:14.100 回答
0

在 Java 中,当您执行“hello”时,java 编译器会创建一个类似于new String("hello"). 该对象保存在字符串池(String#intern())中。

这样做String i = "hello"。它i通过检查 from 来检查池中是否存在String#intern()。如果是,它会重用它,否则它会创建一个新的并放入池中。请参阅此了解更多信息

于 2013-07-23T11:03:37.373 回答