如果我们在 Java 中对字符串调用 subString() 或 toUpperCase() 等任何方法,会创建多少个 String 对象

问题描述 投票:0回答:2

请考虑以下 2 行 Java 代码:

String s = new String("Hello");
String s1 = s.toUpperCase();

在上面的代码中,当我们在 String 上调用 toUpperCase() 方法时,将创建多少个对象。一个对象是在堆中创建还是在字符串常量池中创建,还是只在堆中创建? 我知道 toUpperCase() 会在堆中创建一个新对象。但是想知道会不会也放到String常量池里

java string jvm
2个回答
3
投票

答案是......这取决于。

我们可以肯定地说的一件事是,无论是

toUpperCase()
还是
subString()
都不会在字符串池
1
中放置一个String。唯一指定为(可能)将
String
添加到字符串池的
String
操作是
intern()
.

我们不能肯定地说

toUpperCase()
subString()
会生成一个新的
String
对象。例如,在 Java 11 中,
str.substring(0)
返回
str
本身。这是一个实现细节,但是许多操作的 javadoc 措辞如此,如果
this
满足要求,则返回
this
是有效的。

在创建新

String
的情况下,创建对象的方式取决于实现。 Java 字符串通常表示为一个
String
对象,它引用了表示字符串字符的后备
char[]
byte[]
。但是在某些 Java 版本中,支持数组可以在多个
String
对象之间共享......在某些情况下。事实上,
substring
是使用共享后备阵列创建
String
的方法之一。

最后,正如一位评论者所指出的,这些东西与现实世界中的 Java 编程无关……除了最极端的情况。通常,你应该让 JVM 处理这种东西。


1 - 它是字符串池而不是“常量字符串池”。 “常量池”实际上是类文件中存在的东西。但是字符串池中可能包含不对应Java常量的字符串。


0
投票

看待这个问题的另一种方法是理解 Java 中的字符串是不可变的。此外,它们是在堆内存中创建的。

String Literals 在堆内存中创建,但也放入字符串池中。

在您的代码中,以下行创建了一个 String 对象(不是文字)

String s = new String("Hello");
所以它在堆中创建了一个对象。它不会向字符串池添加任何内容。

以下行在堆中创建另一个对象。即使它不会向字符串池添加任何内容。

String s1 = s.toUpperCase();
所以,在你的例子中。将在堆中创建 2 个对象。字符串池中不会创建新对象。

看看这个答案

© www.soinside.com 2019 - 2024. All rights reserved.