java - Java中表达式 "new String(...)"的目的是什么?

标签 java string

在查看在线代码示例时,我有时会通过使用 new 运算符将 String 常量分配给 String 对象。

例如:

String s;
...
s = new String("Hello World");

当然,与

相比
s = "Hello World";

我不熟悉这种语法,也不知道其目的或效果是什么。 由于字符串常量通常存储在常量池中,然后以 JVM 用于处理字符串常量的任何表示形式存储,是否会在堆上分配任何内容?

最佳答案

你可能认为你想要new String(String)的一个地方是强制内部字符数组的不同副本,如

small=new String(huge.substring(10,20))

但是,不幸的是,这种行为没有记录在案并且依赖于实现。

当我将大文件(一些高达 20 MiB)读入字符串并在事后将其雕刻成行时,我被这个烧伤了。我最终得到了引用由整个文件组成的 char[] 的行的所有字符串。不幸的是,这无意中保留了对整个数组的引用,因为我坚持的几行比处理文件的时间更长——我被迫使用 new String() 来解决它,因为快速处理 20,000 个文件会消耗大量 RAM。

执行此操作的唯一与实现无关的方法是:

small=new String(huge.substring(10,20).toCharArray());

不幸的是,这必须复制数组两次,一次用于 toCharArray(),一次用于 String 构造函数。

需要有记录的方法来通过复制现有字符串的字符来获取新字符串;或者 String(String) 的文档需要改进以使其更加明确(那里有一个暗示,但它相当模糊并且可以解释)。

假设文档未说明内容的陷阱

针对不断出现的评论,观察 new String() 的 Apache Harmony 实现是什么:

public String(String string) {
    value = string.value;
    offset = string.offset;
    count = string.count;
}

没错,那里没有底层数组的副本。然而,它仍然符合 (Java 7) String 文档,因为它:

Initializes a newly created String object so that it represents the same sequence of characters as the argument; in other words, the newly created string is a copy of the argument string. Unless an explicit copy of original is needed, use of this constructor is unnecessary since Strings are immutable.

突出的部分是“参数的副本字符串”;它没有说“参数字符串的副本和支持该字符串的底层字符数组”。

注意您对文档而不是一个实现进行编程。

关于java - Java中表达式 "new String(...)"的目的是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/390703/

相关文章:

c - 被覆盖的字符串数组

java - 我将如何创建一个自定义图形类供paintComponent使用?

string - 在 Scala 中实现不区分大小写比较的字符串类

ruby - 检测字符串中的字符

c - 读/写 txt 字符串

python - 使用 WSDiscovery 从服务列表中获取特定字符串

java - DTO应该使用继承还是组合

java - 解析 Joda 时间部分

java - 字符串到 GZIPOutputStream

java - 使用 Java 从 Azure API 获取 CPU 使用情况