> 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);