Why String class has copy constructor? [duplicate]

Possible Duplicate:
What is the purpose of the expression “new String(…)” in Java?

If immutable classes objects copies would be equal to the originals then why does the String class in Java have a copy constructor? Is it a mistake or there is a reason behind this implementation? In the Java docs it is specified that:

/**
 * Initializes a newly created {@code String} object so that it represents
 * the same sequence of characters as the argument; in other words, the
 * newly created string is a copy of the argument string. Unless an
 * explicit copy of {@code original} is needed, use of this constructor is
 * unnecessary since Strings are immutable.
 *
 * @param  original
 *         A {@code String}
 */
 public String(String original) {
 ....
 ....}

Solution 1:

The main reason to copy a string is to "trim the baggage", that is to trim the underlying char array to only what is necessary.

The underlying char array can mainly be too big because when you create a string by calling substring, the char array can be shared between the new string instance and the source string instance; an offset points to the first character and the length is included.

The expression I use, "trim the baggage", is taken from the source code of String copying constructor :

  164       public String(String original) {
  165           int size = original.count;
  166           char[] originalValue = original.value;
  167           char[] v;
  168           if (originalValue.length > size) {
  169               // The array representing the String is bigger than the new
  170               // String itself.  Perhaps this constructor is being called
  171               // in order to trim the baggage, so make a copy of the array.
  172               int off = original.offset;
  173               v = Arrays.copyOfRange(originalValue, off, off+size);
  174           } else {
  175               // The array representing the String is the same
  176               // size as the String, so no point in making a copy.
  177               v = originalValue;
  178           }
  179           this.offset = 0;
  180           this.count = size;
  181           this.value = v;

This is something many developers forget and is important because a small string may prevent the garbaging of a bigger char array. See this related question where I already pointed this : Java not garbage collecting memory. Many developers consider than the decision of Java designers to use this old optimization trick that was familiar to C coders did, in fact, more harm than good. Many of us know it because we were bitten by it and did have to look into Sun's source code to understand what happened...

As Marko points out (see comments below), in OpenJDK, starting from java 7 Update 6, substring doesn't share the char array anymore and the String(String) constructor is, thus, useless. But it's still fast (even faster in fact) and as this change hadn't been propagated to all VM (and probably not all your customers) I'd recommend to keep this best-practice to use new String(substring) when the old behavior was justifying it.