> On Apr 18, 2016, at 3:30 PM, Stuart Marks <[email protected]> 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);