0

It make sense to make class String objects immutable with following declarations, because they share the same storage in common pool.

String str1 = "abc";
String str2 = "abc";

But, am not sure, if it make sense to have class String objects immutable with following explicit constructor declarations, because they do not share the same storage in heap.

String str3 = new String("def");
String str4 = new String("def");

So, if the content of a class String object has to be modified frequently, it is recommended to learn class StringBuffer and class StringBuilder.

Does it make sense to know, What is the reason that class String has been designed to maintain immutable content with an explicit constructor?

  • @StevenBurnap am not sure, if this is the query in your posted link. My query is about explicit constructors. if String object is mutable with explicit constructor, I would not need to learn StringBuffer and StringBuilder. I understand the idea of same storage with usage of string literal declarations for optimization. – overexchange Nov 28 '14 at 5:55
  • @MichaelT i read the first para from the posted link mentioning: shared mutables are problematic. yes, String str = "abc" they are. But am thinking about new String("abc"); Why are they immutable? – overexchange Nov 30 '14 at 2:13
9

Of course it makes sense.

When you get the value you should not care how it was constructed.

It would make no sense if immutability would be dependent of the way an object was constructed:

"abc" immutable, new String("def") mutable. It would create a mess.

| improve this answer | |
  • oh ok, so, In big apps, one has to keep in mind that this is String object so immutable. I got u. – overexchange Nov 30 '14 at 2:16
3

Java strings have to be immutable because Java's security model depends on the value of them not changing between them being inspected by a SecurityManager instance and consumed by whatever part of the runtime is being protected by the SecurityManager.

For example, if you have a SecurityManager on your thread and you execute:

String str = new String ("innocent.txt");
new FileReader(str);

what happens is that the filename is checked by calling the security manager's canRead method, and only if that allows the access is the file opened.

But if we could start another thread that could modify the string to a value that wouldn't be allowed by the security manager between the call to canRead and the file being opened, we could subvert the security and preform operations we're not supposed to be allowed to do.

An alternative solution would be to make defensive copies of any security-critical string, but this would (1) be error-prone and (2) make the runtime less efficient.

| improve this answer | |
  • Good example of why immutable strings are used. – Neil Nov 28 '14 at 9:38
  • You should know that Java strings are mutable if you use reflection, so they are technically not immutable. – Johan Nov 28 '14 at 13:46
  • @Johan I thought you could disallow modifying private fields with the security manager? – Doval Nov 28 '14 at 14:31
2

Immutability for strings has a lot of advantages even with an explicit constructor (I am sure you know them already: cheap copies, no side-effects, value semantics). The explicit constructor is exactly what everyone expects to be available, without it we would always have to write something ugly like

 String s = (new StringBuilder("abc").toString());

The only caveat, where the classic value semantics fails, is the point you asked for: with

String str3 = new String("def");
String str4 = new String("def");

the equality test str3==str4 will fail (one has to use equal instead), something one would expect to work for classic value semantics.

So the design flaw here is neither the immutability nor the fact there is an explicit constructor for strings, but only the fact the creators of Java did not design the language in a way == works as expected. But that is a minor price to pay for not having every string constructed by the tedious string builder line above.

| improve this answer | |
1

The constructor public String(String original) is a copy constructor. Its sole purpose is to make a copy of a String object.

Since String is immutable, making copies is rarely needed. That has been covered in the Javadoc of that constructor. However, since String is a core class and it is used everywhere, there could be some special cases requiring copying a String.

The String class has plenty of constructors which are rarely needed in most applications. Actually, using any String constructor to create a new String object is not a common way to get hold of a String in most applications.

| improve this answer | |
0

They are immutable so they behave like values. You can pass reference to the string and don't have to fear that whatever code you passed it to might change it.

| improve this answer | |
0

The explicit constructor is a so-called copy constructor. It's intended for the rare case where you need to make sure that you receive a new String instance instead of a pooled one. The newly created string still is immutable, as you can't modify the passed in string reference.

| improve this answer | |

Not the answer you're looking for? Browse other questions tagged or ask your own question.