java为什么要new_字符串是Java中的对象,那么为什么我们不使用“new”来创建它们呢?...

字符串是Java中的对象,那么为什么我们不使用“new”来创建它们呢?

我们通常使用new关键字创建对象,例如:

Object obj = new Object();

字符串是对象,但我们不使用new来创建它们:

String str = "Hello World";

为什么是这样? 我可以用new制作一个字符串吗?

14个解决方案

123 votes

除了已经说过的内容之外,Java中的字符串文字[即字符串如.equals()但不像==]被实习 - 这意味着每次你引用" abcd"时,你都会得到一个单一的引用 String实例,而不是每次都是新的。 所以你将拥有:

String a = "abcd";

String b = "abcd";

a == b; //True

但如果你有

String a = new String("abcd");

String b = new String("abcd");

那么它有可能

a == b; // False

(如果有人需要提醒,请始终使用.equals()来比较字符串; ==测试物理相等性)。

实习字符串文字很好,因为它们经常被使用多次。 例如,考虑(设计)代码:

for (int i = 0; i < 10; i++) {

System.out.println("Next iteration");

}

如果我们没有字符串的实习,那么#34;下一次迭代&#34; 需要实例化10次,而现在它只会被实例化一次。

danben answered 2019-08-10T15:31:50Z

30 votes

字符串是特殊的&#34; Java中的对象。 Java设计人员明智地决定使用Strings,以至于他们需要自己的语法和缓存策略。 当你通过说:

String myString = "something";

myString是对String对象的引用,其值为&#34;某些&#34;。 如果你以后声明:

String myOtherString = "something";

Java非常聪明,可以确定myString和myOtherString是相同的,并将它们作为同一个对象存储在全局String表中。 它依赖于您无法修改字符串来执行此操作的事实。 这样可以降低所需的内存量,并可以更快地进行比较。

相反,如果你写的话

String myOtherString = new String("something");

Java将为您创建一个全新的对象,与myString对象不同。

Jamie McCrindle answered 2019-08-10T15:32:49Z

14 votes

String a = "abc"; // 1 Object: "abc" added to pool

String b = "abc"; // 0 Object: because it is already in the pool

String c = new String("abc"); // 1 Object

String d = new String("def"); // 1 Object + "def" is added to the Pool

String e = d.intern(); // (e==d) is "false" because e refers to the String in pool

String f = e.intern(); // (f==e) is "true"

//Total Objects: 4 ("abc", c, d, "def").

希望这清除了一些疑虑。:)

Crocode answered 2019-08-10T15:33:14Z

6 votes

这是一条捷径。 它原本不是那样的,但Java改变了它。

这个FAQ简要介绍了它。 Java规范指南也讨论了它。 但我无法在网上找到它。

Malfist answered 2019-08-10T15:33:48Z

6 votes

字符串需要进行一些优化(因为缺少更好的短语)。 请注意,String也有运算符重载(对于+运算符) - 与其他对象不同。 所以这是一个特例。

Brian Agnew answered 2019-08-10T15:34:14Z

3 votes

我们通常使用String文字来避免创建不必要的对象。 如果我们使用new运算符来创建String对象,那么它每次都会创建新对象。

例:

String s1=“Hello“;

String s2=“Hello“;

String s3= new String(“Hello“);

String s4= new String(“Hello“);

对于内存中的上述代码:

58f24b5f7bd1b2072dc5129aad955c3f.png

Joby Wilson Mathews answered 2019-08-10T15:34:48Z

2 votes

在Java中,字符串是一种特殊情况,其中许多规则仅适用于字符串。 双引号使编译器创建一个String对象。 由于String对象是不可变的,因此这允许编译器实现多个字符串,并构建更大的字符串池。 两个相同的String常量将始终具有相同的对象引用。 如果您不希望出现这种情况,那么您可以使用新的String(&#34;&#34;),这将在运行时创建一个String对象。 intern()方法过去很常见,可以根据字符串查找表检查动态创建的字符串。 在interned中的字符串后,对象引用将指向规范的String实例。

String a = "foo";

String b = "foo";

System.out.println(a == b); // true

String c = new String(a);

System.out.println(a == c); // false

c = c.intern();

System.out.println(a == c); // true

当类加载器加载一个类时,所有String常量都会添加到String池中。

brianegge answered 2019-08-10T15:35:25Z

0 votes

句法糖。该

String s = new String("ABC");

语法仍然可用。

Seva Alekseyev answered 2019-08-10T15:36:03Z

0 votes

您仍然可以使用new String("string"),但是创建没有字符串文字的新字符串会更难...您必须使用字符数组或字节:-)字符串文字有一个额外的属性:来自任何类的所有相同的字符串文字指向相同的 字符串实例(它们被实习)。

Peter Štibraný answered 2019-08-10T15:36:35Z

0 votes

由于文字(引号中的字符)已经是加载主机类时创建的String对象,因此几乎不需要新的字符串。 在文字和don上调用方法是完全合法的,主要区别在于文字提供的便利。 如果我们必须创建一个字符数组并用char填充char并且它们执行一个新的String(char数组),那将是一个主要的痛苦和浪费。

mP. answered 2019-08-10T15:37:04Z

0 votes

随意创建一个新的String

String s = new String("I'm a new String");

通常的表示法s = "new String";或多或少是一个方便的快捷方式 - 应该用于性能原因,除了那些非常罕见的情况,你真的需要符合条件的字符串

(string1.equals(string2)) && !(string1 == string2)

编辑

回应评论:这不是一个建议,而只是对提问者论文的直接回应,我们不会使用新的&#39; 字符串的关键字,根本不是真的。 希望这个编辑(包括上面的内容)澄清一点。 顺便说一下 - 关于SO的上述问题有几个好的和更好的答案。

Andreas_D answered 2019-08-10T15:37:53Z

0 votes

文字池包含在不使用关键字new的情况下创建的任何字符串。

有一个区别:没有新引用的字符串存储在String文字池中,而带有new的字符串表示它们位于堆内存中。

具有new的字符串在内存中的其他位置就像任何其他对象一样

lavina answered 2019-08-10T15:38:34Z

0 votes

因为String是java中的不可变类。

现在为什么它是不可改变的?因为String是不可变的所以它可以在多个线程之间共享,我们不需要在外部同步String操作。由于String也用于类加载机制。 因此,如果String是可变的,则java.io.writer可能已更改为abc.xyz.mywriter

Mr37037 answered 2019-08-10T15:39:09Z

0 votes

TString obj1 = new TString("Jan Peter");

TString obj2 = new TString("Jan Peter");

if (obj1.Name == obj2.Name)

System.out.println("True");

else

System.out.println("False");

输出:

真正

我创建了两个单独的对象,都有一个字段(ref)&#39; Name&#39;。 所以即使在这种情况下,#Jan; Jan Peter&#34; 如果我理解java处理的方式,那就是共享的

Pete Del Fina answered 2019-08-10T15:39:42Z


版权声明:本文为weixin_42524499原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。