There is an interesting statement in Joshua Bloch’s “Effective Java”, 2nd edition, chapter 4, item 15:
A consequence of the fact that immutable objects can be shared freely is that
you never have to make defensive copies (Item 39). In fact, you never have to
make any copies at all because the copies would be forever equivalent to the originals.
Therefore, you need not and should not provide a clone
method or copy
constructor (Item 11) on an immutable class. This was not well understood in the
early days of the Java platform, so the String
class does have a copy constructor,
but it should rarely, if ever, be used (Item 5).
(page 76 in my copy)
I think, Joshua Bloch can be seen as an authoritative source, especially as James Gosling, one of the Java inventors, has been cited saying, “I sure wish I had this book ten years ago…” (referring to the 1st edition from 2001).
So the existence of the String(String)
constructor can be seen as a design mistake, much as the parameterless String()
constructor. Note also the presence of the factory methods String.valueOf(char[])
/ String.valueOf(char[],int,int)
and String.copyValueOf(char[])
/ String.copyValueOf(char[],int,int)
, whose naming suggests a fundamental difference that simply isn’t there. The immutable nature of String
mandates that all variants create a defensive copy of the provided array, to protect against subsequent modifications. So the behavior is exactly the same (the documentation tells this explicitly), whether you use valueOf
or copyValueOf
.
That said, there are some practical use cases, though not necessarily being within original intentions. Some of them are described in the answers to this question. As the new
operation guarantees to produce a new instance, it might be useful for any subsequent operation relying on a distinct identity, e.g. synchronizing on that instance (not that this was a good idea) or trying to recognize that instance via identity comparison to be sure that it doesn’t originate from an external source. E.g., you might want to distinguish between a property’s default value and a value that has been explicitly set. This, however, is of limited use as other code might not guaranty to maintain the object identity in its operations, even if the string contents doesn’t change. Or it might remember your special instance and reuse it, once it encountered the string.
Before Java 7, update 6, String
had an offset
and length
field, allowing a cheap substring
operation, referring to a range within the original array, without copying. This led to the scenario, that a (conceptually) small string could hold a reference to a rather large array, preventing its garbage collection. For the reference implementation (that shipped by Sun/later Oracle), recreating the string via the String(String)
constructor produced a String
with a fresh copy of the array, occupying only as much memory as needed. So this was a use case incorporating an implementation specific fix to an implementation specific problem…
Current Java releases do not maintain these offset
and length
fields, implying a potentially more expensive substring
operation, but no copying behavior in the String(String)
constructor anymore. This is the version, whose source code you have cited in the question. The older version can be found in this answer.