-1

The String constructor that takes a string literal argument has the following implementation.

   @IntrinsicCandidate
    public String(String original) {
        this.value = original.value;
        this.coder = original.coder;
        this.hash = original.hash;
    }

From what I understand, the value of the original String literal(argument passed) gets assigned to the newly created object in the heap memory. So, we have two objects, one in the string literal pool and another in the heap memory. I'm assuming since the String literal pool does not get garbage collected, the created literal will stay in the literal pool till the end of the application. Isn't that waste of memory resources?

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.

I believe this comment from the source code, suggests that we do not use this constructor unless an explicit copy is needed, and it is unnecessary since Strings are immutable. Are they suggesting we don't use it since it is wasteful or is there any other reason behind that? If they are indeed suggesting not to use it since it is wasteful, why do they even have this and the parameter less constructor implemented(the comment there also says its unnecessary)?

Couldn't they have just had the constructors that take a character array, byte array etc... instead of these two constructors?

Java String creation and String pool The above thread answers that a string literal does get created when you use new String("Argument"), but what I want to know is why they decided to have the String() and String("argument") if it is wasteful and they themselves are suggesting to not to use it?

1
  • Notes: 1) the constructor does not only take literal strings, it takes ANY kind of string; 2) even the literal string is saved somewhere, only a reference to it is stored in the string pool (for interned strings); 3) strings in the String pool will eventually get collected, despite unlikely Commented Jan 22, 2024 at 9:30

1 Answer 1

2

That this constructor exists has historical reasons.

In early versions of Java 1.7 and previous versions (also checked Java 1.5) the substring(int, int) method was optimized so that the returned string shared the backing character array with the original string (excerpt which calls an internal constructor):

public String substring(int beginIndex, int endIndex) {
    new String(offset + beginIndex, endIndex - beginIndex, value);
}

package private constructor:

String(int offset, int count, char value[]) {
    this.value = value;
    this.offset = offset;
    this.count = count;
}

This had the benefit that the following operation did not copy characters:

String s1 = readSomeLongStringFromAFile("somefile.txt");
String s2 = s1.substring(2, s1.length()-2);

It had the drawback that in the following case the backing character array might have been retained in memory even if it was not reused:

String getStartFromFile(String filename) {
    String s1 = readSomeLongStringFromAFile("somefile.txt");
    String s2 = s1.substring(0, 2);
    return s2;
}

In this case it was beneficial to use the copy constructor, since the copy constructor copied just the needed characters from the backing array:

String getStartFromFile(String filename) {
    String s1 = readSomeLongStringFromAFile("somefile.txt");
    String s2 = s1.substring(0, 2);
    return new String(s2);
}

The linked sources are from Java 1.7-b24, in the latest version of Java 1.7 (1.7u351-ga) this package private constructor is gone.

However there is still code out there that uses the String(String) constructor and Java tries to as much as possible avoid breaking existing code, which means that the String(String) copy constructor is here to confuse people.

Sign up to request clarification or add additional context in comments.

1 Comment

I wouldn't say it's there to confuse people. The documentation clearly states "Note that use of this constructor is unnecessary since Strings are immutable." for the no-arg constructor and "Unless an explicit copy of original is needed, use of this constructor is unnecessary since Strings are immutable." for the other. They could have deprecated them though.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.