在查看在线代码示例时,我有时会通过使用new运算符将String常量赋值给String对象.
例如:
String s; ... s = new String("Hello World");
当然,这与之相比
s = "Hello World";
我不熟悉这种语法,也不知道目的或效果是什么.由于String常量通常存储在常量池中,然后以JVM处理String常量的任何表示形式存在,甚至还会在堆上分配任何内容?
您可能需要的一个地方new String(String)
是强制子字符串复制到新的基础字符数组,如
small=new String(huge.substring(10,20))
但是,遗憾的是,这种行为没有记录,并且依赖于实现.
当我将大文件(一些高达20 MiB)读入一个字符串并在事后将其雕刻成行后,我就被这个烧了.我最后得到了引用由整个文件组成的char []的行的所有字符串.不幸的是,无意中保留了对整个数组的引用,因为我所持有的几行比处理文件的时间更长 - 我被迫用new String()
它来解决它.
唯一的实现不可知的方法是:
small=new String(huge.substring(10,20).toCharArray());
遗憾的是,必须toCharArray()
在String构造函数中复制数组两次,一次为一次,一次为一次.
需要有一种记录的方法来通过复制现有字符串来获取新的字符串; 或者String(String)
需要改进的文件以使其更加明确(这里有一个含义,但它的解释相当模糊和开放).
为了回应那些不断涌现的评论,请观察Apache Harmony实现的内容new String()
:
public String(String string) { value = string.value; offset = string.offset; count = string.count; }
没错,那里没有底层数组的副本.然而,它仍然符合(Java 7)String文档,因为它:
初始化一个新创建的String对象,使其表示与参数相同的字符序列; 换句话说,新创建的字符串是参数字符串的副本.除非需要显式的原始副本,否则不必使用此构造函数,因为字符串是不可变的.
显着的部分是"参数字符串的副本"; 它没有说"参数字符串的副本和支持字符串的基础字符数组".
请注意您编写文档而不是一个 实现.
我发现这个有用的唯一一次是声明锁变量:
private final String lock = new String("Database lock"); .... synchronized(lock) { // do something }
在这种情况下,Eclipse等调试工具会在列出当前持有或正在等待的线程锁定时显示该字符串.您必须使用"new String",即分配一个新的String对象,否则共享字符串文字可能会被锁定在其他一些不相关的代码中.