Java中的字符串字面量 vs 字符串对象

3
在Java中,可以使用以下两种方式创建字符串:
  1. String foo = "Test";
  2. String fooobj = new String("Test");
通常会提到这两种创建字符串的方式之间的区别。我想更多地了解在哪些适当的情况下,我们应该选择哪种方式
  String foo="Test";

何时选择使用

 String fooobj=new String("Test");  ?

请查看以下内容: https://dev59.com/bXA75IYBdhLWcg3wbojM - Abed Hawa
1
我并不是在问这两者的区别:String foo="Test"; String fooobj=new String("Test"); 请先仔细阅读我的问题。 - kedar kamthe
我想不出使用new String("...")的好理由。 - NomadMaker
6个回答

11
简短的回答:如果你有任何疑虑,你不需要new String("literal here")。如果你需要它,你会知道你需要它和为什么需要它。
长的回答:
基本上,你只有在想确保生成的字符串对象不等于任何其他字符串对象时才需要使用new String("literal here")。字面量会自动进行interned处理;通过new String("literal here")创建的字符串则不会。
那么为什么要这样做呢?答案是几乎永远不需要,因为String实例是不可变的,所以你不必担心是否与其他东西共享String实例。我能想象到的唯一场景是,如果你有一个接受String的API,并且你想要一个除null以外的标记值,并且你想通过==检查该标记值,就像这样:
public static final String MARKER = new String("Marker");
public void someFictionalMethod(String arg) {
    if (arg == MARKER) {
        // Take action on the marker
    }
    else {
        // Take action on the string
    }
}

即使如此,我仍然会觉得有些可疑,并会探索其他方法来完成它。


1
这是事实。但这种需求是如此罕见,以至于使另一个答案(“从不需要”)几乎正确。 - Joachim Sauer

7

使用字符串时,不必每次都创建一个新的字符串对象。

String fooobj = new String("Test");

因此,你永远不应该这样做。只需编写 String fooobj = "Test"; 即可。

String类是不可变的。这意味着在构造了String对象之后,其内容无法更改。在使用字符串字面值时,不需要创建显式副本。


3

您永远不应该使用new String()来创建字符串。每次以这种方式创建字符串时,都会在内存中创建一个新对象。如果您编写String s = "aaa",则有可能在给定的JVM中已经创建了这样的对象,它存储在字符串池中,因此您的变量将只是对该现有对象的引用-通过这种方式可以节省内存。


0

当你使用第二种方法时,实际上依赖于第一种方法来初始化构造函数的参数。

那么问题是,如果你可以通过第一种方法创建String对象,为什么要费额外的力气使用第二种方法呢?

我没有看到任何场景需要使用第二种构造函数样式,所以始终坚持使用第一种方法。


0

String 对象和字符串字面值之间有微妙的差别。

String s = "abc"; // 创建一个 String 对象和一个引用变量 在这个简单的情况下,“abc”将进入池中,s 将引用它。

String s = new String("abc"); // 创建两个对象和一个引用变量 在这种情况下,因为我们使用了 new 关键字,Java 会在正常(非池)内存中创建一个新的 String 对象,并且 s 将引用它。此外,字面值“abc”将被放置在池中。


-1

字符串是常量,一旦创建后其值就不能被改变。字符串缓冲区支持可变字符串。由于字符串对象是不可变的,因此它们可以被共享。例如:

     String str = "abc";

等同于:

     String str = new String("abc");

你应该避免使用第二种方式声明字符串,原因在其他答案中已经解释过了。


@ Don:您只需要看一下这里的其他答案。您说String str = "abc";等同于String str = new String("abc");,这是完全错误的。 - T.J. Crowder
@T.J.Crowder:如果我们谈论“字符串比较”和“对象比较”,我完全同意。但是这里问的是这两种不同声明之间的区别。由于Java程序中的所有字符串字面量(例如“abc”)都被实现为该类的实例,因此唯一的区别是所有答案所显示的那些区别。但请看这个:http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/String.html - DonCallisto
@ Don: 这个问题是关于创建字符串而不是声明字符串的,以及在什么情况下使用哪种形式是合适的。你的回答(请原谅,不要误解我对你的态度)提供了错误的信息(它们是等价的,因为有自动内部化的原因),并且没有涉及到问题的实质(每种情况下何时使用哪种形式),所以我认为这就是为什么它会引起负评的原因。 - T.J. Crowder
1
@T.J.Crowder 好的,不要“害怕”解释您的想法:我不会冒犯:) 所以,如果我从另一个角度看问题,我认为您是有道理的。但是我不会删除我的答案,因为它也可以“有用”,帮助人们了解“错误”在哪里 :) - DonCallisto

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接