Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use of the String(String) constructor in Java [duplicate]

I've read on articles and books that the use of String s = new String("..."); should be avoided pretty much all the time. I understand why that is, but is there any use for using the String(String) constructor whatsoever? I don't think there is, and don't see any evidence otherwise, but I'm wondering if anyone in the SO commmunity knows of a use.

like image 915
Ryan Thames Avatar asked Jan 21 '09 14:01

Ryan Thames


People also ask

How do you duplicate a string in Java?

Here is the shortest version (Java 1.5+ required): repeated = new String(new char[n]). replace("\0", s); Where n is the number of times you want to repeat the string and s is the string to repeat.

What is use of copy constructor in Java?

A copy constructor in a Java class is a constructor that creates an object using another object of the same Java class. That's helpful when we want to copy a complex object that has several fields, or when we want to make a deep copy of an existing object.

What is a string constructor?

The String constructor is used to create a new String object. When called instead as a function, it performs type conversion to a primitive string, which is usually more useful.

Can we copy the constructor in Java?

Generally, the copy constructor is a constructor which creates an object by initializing it with an object of the same class, which has been created previously. Java supports for copy constructors but unlike C language, Java does not provide an explicit copy constructor you need to define it yourself.

Can we copy string in Java?

As we know that String is an immutable object, so we can just assign one string to another for copying it. If the original string value will change, it will not change the value of new String because of immutability.

How do you make a copy of a string?

strcpy can be used to copy one string to another. Remember that C strings are character arrays. You must pass character array, or pointer to character array to this function where string will be copied. The destination character array is the first parameter to strcpy .


2 Answers

This is a good article: String constructor considered useless turns out to be useful after all!

It turns out that this constructor can actually be useful in at least one circumstance. If you've ever peeked at the String source code, you'll have seen that it doesn't just have fields for the char array value and the count of characters, but also for the offset to the beginning of the String. This is so that Strings can share the char array value with other Strings, usually results from calling one of the substring() methods. Java was famously chastised for this in jwz' Java rant from years back:

The only reason for this overhead is so that String.substring() can return strings which share the same value array. Doing this at the cost of adding 8 bytes to each and every String object is not a net savings...

Byte savings aside, if you have some code like this:

// imagine a multi-megabyte string here  
String s = "0123456789012345678901234567890123456789";  
String s2 = s.substring(0, 1);  
s = null;

You'll now have a String s2 which, although it seems to be a one-character string, holds a reference to the gigantic char array created in the String s. This means the array won't be garbage collected, even though we've explicitly nulled out the String s!

The fix for this is to use our previously mentioned "useless" String constructor like this:

String s2 = new String(s.substring(0, 1));  

It's not well-known that this constructor actually copies that old contents to a new array if the old array is larger than the count of characters in the string. This means the old String contents will be garbage collected as intended. Happy happy joy joy.

Finally, Kat Marsen makes these points,

First of all, string constants are never garbage collected. Second of all, string constants are intern'd, which means they are shared across the entire VM. This saves memory. But it is not always what you desire.

The copy constructor on String allows you to create a private String instance from a String literal. This can be very valuable for constructing meaningful mutex objects (for the purposes of synchronization).

like image 159
mmcdole Avatar answered Sep 18 '22 14:09

mmcdole


Just to expand on Douglas's answer*, I can give a firm example of where I've used it. Consider reading a dictionary file, with thousands of lines, each one of them just a single word. The simplest way of reading this is to use BufferedReader.readLine().

Unfortunately, readLine() allocates a buffer of 80 characters by default as the expected line length. This means that usually it can avoid pointless copying - and a bit of wasted memory isn't normally too bad. However, if you're loading a dictionary of short words in for the duration of the application, you end up with a lot of memory being permanently wasted. My "little app" sucked up far more memory than it should have done.

The solution was to change this:

String word = reader.readLine();

into this:

String word = new String(reader.readLine());

... with a comment, of course!

* I can't remember whether I was working with Douglas when this actually cropped up, or whether it's just coincidence that he answered this particular question.

like image 33
Jon Skeet Avatar answered Sep 18 '22 14:09

Jon Skeet