1

I understand that a String variable in Java is immutable and can therefore not be changed.

String myString = "Hello.";
myString += " ";
myString += "My name is Kevin"; 

Each time we "add" something to this String(), we are effectively creating a new String(), but this has the same name as the string it is being concatenated with. Does this mean there are multiple references in memory with the variable "myString"?

Shaney96
  • 75
  • 1
  • 9
  • You are misunderstanding the difference between a reference and the actual object its refering to. When you concatenate, the reference just points to the newly created string object. – Yassin Hajaj Jul 09 '16 at 10:32
  • 1
    What you call a _name_ is in fact called a _variable_. Objects and references do not have a name. A variable can refer to different objects at different times, and different variables can refer to the same object - which is called _aliasing_. – Seelenvirtuose Jul 09 '16 at 10:35

5 Answers5

6

Each time you "modify"/concatenate the String with +=, you're creating a new String object and replacing the reference named myString with the newly-created String. So no, there is only one reference in memory, but the object the reference points to changes each time. The string is immutable, so the object cannot be modified "in place".

String is an immutable class in Java. An immutable class is simply a class whose instances cannot be modified. All information in an instance is initialized when the instance is created and the information can not be modified. There are many advantages of immutable classes.

There is a great answer on the Programmer's StackExchange explaining why Strings are immutable in Java, and more details about how exactly this works.

The best way to do this is to just use the StringBuilder() class:

String myStringBuilder = new StringBuilder("Hello.");
myStringBuilder.append(" ");
myStringBuilder.append("My name is Kevin");

System.out.println(myStringBuilder.toString());

However, String concatenation is translated into StringBuilder operations automatically by modern Java compilers.

Community
  • 1
  • 1
Will
  • 24,082
  • 14
  • 97
  • 108
  • If there is only one reference in memory then why is this form of `String` modification considered inefficient compared to say, using `StringBuilder()` instead? Surely if there is only a single reference then the memory-usage is unchanged when modifying the `String` using `+=`? – Shaney96 Jul 09 '16 at 10:33
  • Because using `+=` requires the creation of new `String()` objects each time, whereas `StringBuilder()` is mutable and can be modified in-place. – Will Jul 09 '16 at 10:38
  • Thank-you for your answer and explanation. – Shaney96 Jul 09 '16 at 10:40
  • No problem, glad to help! I added some more information in my edit. – Will Jul 09 '16 at 10:42
  • 1
    I actually already have that exact code in my program, I understand how String builder works I was just trying to get my head around how the original method is less efficient if there is only one reference in memory. So a new reference is created but the older references for the variable are left for the garbage collector (check Mehdi's answer)? – Shaney96 Jul 09 '16 at 10:47
  • 1
    Got it; maybe the edit will help some people who haven't used `StringBuilder` before. Right, the old `String` object will be garbage collected fairly quickly, as there is no longer any reference to the old object. – Will Jul 09 '16 at 10:49
  • 1
    Thanks. I fully understand now, I am new to Java and have never come across "garbage collecting" in programming before. – Shaney96 Jul 09 '16 at 10:55
2

No , you can not access to previous reference and it's left for garbage collector to collect it. in other words there is only one reference in memory which holds the current value of variable("My Name is Kevin)

note that if you r gonna change a String variable a lot , you should use StringBuilder class.

here is link to Documentation of StringBuilder class you also can find lots example for using this class on internet

https://docs.oracle.com/javase/8/docs/api/java/lang/StringBuilder.html

also here is detailed answer of your question

When will a string be garbage collected in java

Community
  • 1
  • 1
  • So the previous versions of the `myString` variable are still present in memory but, because they are no longer referred to, they will be left for the "garbage collector"? – Shaney96 Jul 09 '16 at 10:42
  • yes , as u can see in the link i added to answer, rules for garbage collecting in the strings are same as others. – Mehdi Hamzezadeh Jul 09 '16 at 11:35
2
String myString = "Hello.";

The above create a new Object and put "Hello." into memory which myString is reference to the Object.

myString += " ";

Here you can look as myString = myString + " "; a " " String is created and put into memory and the concatenation will result to create a new String which is referenced by myString.

Note that String concatenation with "+" has a O(N2) complexity while StringBuilder has O(N) in complexity. It is becase new String is created for the concatenation result every time while StringBuilder instead contains a sequence of characters. Therefore String concatenation is less efficient than using a StringBuilder especially need to build up a large amount of String.

Wilson
  • 11,339
  • 2
  • 29
  • 33
2

Java uses a string pool. This is an implementation of the concept of string interning.

In computer science, string interning is a method of storing only one copy of each distinct string value, which must be immutable. Interning strings makes some string processing tasks more time- or space-efficient at the cost of requiring more time when the string is created or interned. The distinct values are stored in a string intern pool.

This means that for every string, a copy of that particular string is added to the string pool. Every variable that holds that exact string, points to that copy in the string pool.


The strings Hello., , and My name is Kevin are added to the string pool, since they're literals in the program.

String myString = "Hello.";

The variable myString starts pointing to the string Hello., which is already in the string pool.

myString += " ";

The string Hello. (note the extra space at the end) is added to the pool. The variable myString now points to that.

myString += "My name is Kevin";

The string Hello. My name is Kevin is added to the pool. The variable myString now points to that.
Strings in the pool that are no longer being referenced by variables, are eligible for garbage collection, so Hello. (with the space at the end), can now be garbage collected.

Community
  • 1
  • 1
SQB
  • 3,926
  • 2
  • 28
  • 49
  • So by "may be cleaned out" you're saying that there are addresses in memory that are being used by older versions of `myString` but will be cleaned at compile-time? – Shaney96 Jul 09 '16 at 10:49
1

here your Code in which you define a String reference variable myString.

String is a immutable class, it means there is no modification can be made in object once it created.

Here "Hello" creates a String Object and refer the object by myString.

String myString = "Hello.";  //create a Object String contain Hello and refer to myString
myString += " ";
myString += "My name is Kevin";

when myString+=" "; getting executed it creates another new object of String by concaticate "Hello" in it.

"Hello " a new Object created and myString refers to it. "Hello" is eligible for garbage Collection.

again when myString += "My name is Kevin"; getting executed, it creates another new Object of String by concatinate "Hello " in it. Your new Object "Hello My Name is Kevin" is referred by myString reference Variable of String Type.

Now, Your both earlier Objects "Hello" and "Hello/s" is not referenced by any other reference variable, So, It is eligible for garbage Collection.

Thanks

Vikrant Kashyap
  • 6,398
  • 3
  • 32
  • 52