> On Apr 18, 2016, at 3:30 PM, Stuart Marks <stuart.ma...@oracle.com> wrote:
> 
> On 4/17/16 7:06 AM, Dave Brosius wrote:
>> Along these lines, is there a reason not to deprecate the
>> 
>> String(String s)
>> 
>> constructor? Now that substring doesn't glom off the original string, i see 
>> no
>> reason for this constructor.
> 
> It's a fair point. But I think that historically there's been much greater 
> awareness of Strings' identity than that of boxed primitives.
> 
> At issue is string interning. When you compile a Java program, a string 
> literal like "foo" is unavoidably interned. This is wired deeply into the 
> language, compiler, and JVM, and has been so since 1.0.
> 
> With boxed primitives, there is autoboxing, but it's only been around since 
> Java 5. ("Only" 11 years.) There is a cache, and although this is mandated by 
> the JLS, it's actually maintained only by the library.
> 
> The notion of identity of strings seems stronger, thus there's a greater need 
> for new String(String) if you want to guarantee a string has a unique 
> identity.
> 
> It also seems much more likely for us to be able to turn boxed primitives 
> into values than to turn strings into values. (One issue is that strings can 
> be of all different sizes, whereas all instances/values of a boxed primitive 
> are of the same size.) Thus there appears to be a greater benefit to 
> migrating code away from the box constructors than from the String(String) 
> constructor.
> 
> This is probably something that should be revisited at some point, though. 
> There are probably more misuses of String(String) out there than there are 
> legitimate uses.

As an example of a useful use of the new String(String) constructor, I once 
wrote (pseudo) code:

WeakHashMap<String, String> memoTable = new WeakHashMap<>();
public String memoTransform(String key) {
    String value = memoTable.get(key);
    if (value != null) return value;
    value = transform(key);  // Might be identity function and return 'key'
    memoTable.put(key, (key == value) ? new String(value) : value);
}

If you aren't careful to copy your value in this sort of situation, you can end 
with
never-collectible entries and therefore memory leaks in your weak hash table.

If substring were specified to always return unique objects, that could work as 
well --
but in my opinion the copy constructor is clearer when object identity is 
important,
and it looks like String sensibly avoids unnecessary copying:

String.java:1933  return (beginIndex == 0) ? this : new String(value, 
beginIndex, subLen);

Reply via email to