Diff在Java中使用新的String(“xyz”)和“xyz”

时间:2011-06-03 09:16:03

标签: java string instantiation

  

可能重复:
  difference between string object and string literal

您好,

最重要的是,让我们用String

提出Java事实

字符串是不可变的    我的问题 - 如果字符串是不可变的,那么下面的语句应该有编译错误!

             String str = "xyz";
                     or
             String str = new String("xyz");

             str = "abc";        //COMPILATION ERROR
                 or
             str = new String("abc");  //COMPILATION ERROR

以下实例化有什么区别?

 String str = "xyz";
      and
 String str = new String("xyz");

阿米特。

5 个答案:

答案 0 :(得分:5)

字符串是不可变的意味着您不能执行str[1] = 'x'之类的操作,即您无法更改字符串的内容。

This会回答你的第二个问题。

答案 1 :(得分:3)

字符串是不可变的,因此您无法更改字符串的内容。

在以下代码中:

String str = "xyz";
str = "abc";

您不是要更改String实例的内容,而是将新的String实例分配给变量str。也就是说,如果你这样做:

String str = "xyz";
String otherStr = str;
String str = "abc";

然后otherStr将保持不变。所以你实际上并没有改变str指向的对象。

至于你的第二个问题

String str = "xyz";

从字符串池中获取值为"xyz"的String对象,而

String str = new String("xyz");

实例化一个新对象。

也就是说,如果你这样做

String a = "xyz", b = "xyz";

您将拥有a == b,而如果您这样做

String a = new String("xyz"), b = new String("xyz");

情况并非如此。 example

有关详细信息,请参阅:

答案 2 :(得分:2)

字符串是不可变的。字符串引用不是。这就是区别。

所以:

String str = "abc";

str是一个变量,指的是一个不可变的字符串“abc”。现在,如果我这样做:

str = "def";

str仍然是一个变量,指的是不同的不可变字符串(“def”)。我可以更改str指向我想要的所有内容,str变量。我无法更改任何字符串的实际内容(因为Java的字符串是不可变的,按设计)。每当你做一些似乎修改字符串的事情(比如toUpperCase)时,它实际上正在做的是创建一个 new 字符串,其中包含旧字符串内容的副本,并以此方式修改描述

让字符串成为不可变的是我知道如果我有一个字符串的引用,那个字符串永远不会改变。传递字符串时,这是一个非常有用的保证。如果我们没有这个保证,我们一直复制字符串只是为了保护自己免受修改它们的人。例如,考虑name属性的标准setter函数:

void setName(String n) {
    this.name = n;
}

如果字符串不是不可变的,我们必须这样做:

void setName(String n) {
    this.name = new String(n); // Blech, duplication
}

...所以我们知道我们的字符串副本不会以我们不期望的方式改变。这会导致内存中字符串数据重复的很多,大部分都是不必要的,因此Java的设计者非常聪明地决定字符串是不可变的,并且您可能想要的任何更改都会创建一个新字符串而不是原位修改旧字符串。 (对于那些确实使用char[]代替的情况,您可以获得就地修改行为。)


关于str = "abc";str = new String("abc")之间差异的单独问题,区别在于后者(使用constructor)保证会返回新的引用,而前者不是。 E.g:

String a = "abc";
String b = "abc";
String c = new String("abc");

a == b(检查引用是否匹配,而不是字符串)将为true,因为文字字符串为interneda == c保证为false,因为我们使用c的构造函数。 a.equals(b)a.equals(c)都是正确的,因为abc都引用equivalent字符串。

答案 3 :(得分:1)

  

如果字符串是不可变的,那么下面   声明应该有汇编   错误!

你误解了不变性概念。看看Prasoon的答案 字符串不变性意味着您无法更改字符串内的内容。

String a = "hello";
String b = "hello";    
System.out.println(a==b);   // returns true.

此处ab两个字符串文字都指向同一个对象。


  

两者之间有什么区别   实例化?

String a = "hello";
String b = "hello";   
System.out.println(a==b); // returns true.

两者都引用相同的字符串文字。

String a = new String("hello");
String b = new String("hello"); 
System.out.println(a==b);  // returns false.

创建了两个不同的字符串对象。

答案 4 :(得分:0)

 String str = "xyz"; 

是一个内部缓存的字符串实例。

 String str = new String("xyz");

是一个未从缓存中实现的新对象

一方面注意以下行为......

"xyz" == "xyz" evals true

new String("xyz") == new String("xyz") evals false

new String("xyz").equals(new String("xyz")) evals true

还要注意Java中的==比较对象引用。