how java handles string literals [duplicate] - java

This question already has answers here:
What is the Java string pool and how is "s" different from new String("s")? [duplicate]
(5 answers)
Closed 9 years ago.
in java, i have created 2 string literals having same value
String a = "Hello";
String b = "Hello";
now both of them should have same reference
System.out.println(a==n); // returns true
but when i do
b+=" World";
System.out.println(a==b); // returns false
Now i have 2 questions here
1. why a and b are not referencing to same object after 'b+=' operation?
2. how come i'm able to change string b without any error?(because i have read String class is immutable)

The reason you can change b is because you're technically making a new String object and assigning it to the existing reference.
b += " World"
is the same as
b = b + " World";
b is technically pointing to a new String object. So to start out, a and b are pointing to the same object, but when b is modified it is now a different object, so a will not equal "Hello World" and a==b will now be false.
For examples of mutable String classes, try StringBuffer or StringBuilder. You can use their .append() method to add to the string, along with other methods to modify it.

When you do b+=" World" you are creating a new string instance, of course this does not point to the same old string anymore.
You are not changing the old string, instead you are creating a new string and assigning it to the variable b. Use the final modifier if you want to always refer to the same object with that variable.

a and b are pointing to a String object. Modifying b, means you are now pointing to a new object.
Because Strings are immutable, when you "modify" a string, a new object is created. That's why the second is no longer the same.

Related

String Reference type in Java versus others in terms of objects [duplicate]

This question already has answers here:
Java Object Assignment
(8 answers)
Closed 2 years ago.
So I was watching an introductory Java tutorial, and it said that if you declare a reference type, and another one equal to that object, if you change the first object, the second one will change as well. For example:
Point p1 = new Point(1, 1);
Point p2 = p1;
p1.x = 5;
System.out.println(p2);
and this would give me an output of
java.awt.Point[x=5,y=1]
However, I tried this with a String:
String s1 = "Hello, World!";
String s2 = s1;
s1 = "Goodbye, World!";
System.out.println(s2);
but I got
Hello, World!
as an output.
Why does this happen, and does it mean that Strings are a special type of reference types because they are used to commonly?
Strings in Java are immutable objects. They never change. When you do a new assignment it simply creates a new String. The old one remains to be collected by the garbage collector. Your Point class is not an immutable object.
I work with a lot of things in python and it is the same situation. Take a list, for example, which has multiple values stored. That will change when you've done the equivalent of your code in python. Strings will not change as you've said. The thing with code is that objects and classes like lists will change because they're not stored in memory. They are merely references, not new objects. When you reassign a string, assignment works properly because it is just one value.
String is a 'special' object in java. It's an immutable object (Fixed and cannot be modified), and would be the only object that can be declared without the new keyword.
If you use StringBuilder, StringBuffer those are mutable String and your values will be modified upon change.
When you dive deeper, Java String comes with many confusing understanding. When you use "==", 2 different string with same value returns the same reference of the memory address. Eg.
String a1 = "abc"
String a2 = "abc"
a1 == a2 //returns true because a1 and a2 points to same reference (but not always!)
a1 == new String("abc") //returns false
/**Do use "equals", not == for string's value comparison**/
If you can wrap your mind around memory object references:
String s1 = "Hello, World!"; //let's say it's allocated to memory address 0x0012
String s2 = s1; //s2 points to same memory address 0x0012
s1 = "Goodbye, World!"; //s1 points to new memory address 0x1113
System.out.println(s2) //printing value in still in memory address 0x0012
It's equivalent as, s1 points to new Object, s2 points to the old Object.
and when you refer back to your Point example
Point p1 = new Point(1, 1);
Point p2 = p1; //p2 is referring to p1's memory address
p1.x = 5;
p1 = new Point(2,2); //Assign to new memory address, here is like the line for s1="Goodbye,world"
System.out.println(p2.x); //You now still get 5, because it's still old object.
So to fix a string that is mutable, you need something like "Class"."method" to change in order to retain the same object being modified. Hence something like:
StringBuilder sb1 = new StringBuilder("Hello World");
StringBuilder sb2 = sb1; //Points to same reference address.
sb1.append("Goodbye World");
System.out.println(sb2.toString()); //Now you get Hello WorldGoodbye World.
sb1.setLength(0).append("Goodbye World"); //clear then set to new value.
System.out.println(sb2.toString()); //Now you get Goodbye World.

difference between two java String assignment types [duplicate]

This question already has answers here:
What is the difference between "text" and new String("text")?
(13 answers)
Difference between string object and string literal [duplicate]
(13 answers)
Closed 8 years ago.
what is the difference between these two implementations :
String s1 = "java";
and
String s2 = new String("java");
is s1 is able to perform all the functions that s2 will do?? like to uppercase, append etc..
The only Difference is String s1 = "java" will create a String Literal and it will be stored in a String Pool And for String s2 = new Sting("java") an Instance object will be created plus a String Literal in String pool.
For Second part Yes you can, Since its a Variable and variable can access library function using dot operator. so s1.toUpperCase() and s2.toUpperCase().
Ex.
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
String s1 = new String("java");
System.out.println(s1.toUpperCase());
String s2 = "java";
System.out.println(s2.toUpperCase());
}
}
Result : JAVA JAVA
For the first part of question, it has been asked many times and answered many times like here and I don't think we need a better answer there
For the second part of your question,
is s1 is able to perform all the functions that s2 will do?? like to
uppercase, append etc..
Absolutely yes! Try "hello".toUpperCase()
String s = "abc"; // creates one String object and one reference variable
In this simple case, "abc" will go in the pool and s will refer to it.
String s = new String("abc"); // creates two objects and one reference variable
In this case, because we used the new keyword, Java will create a new String object
in normal (nonpool) memory, and s will refer to it. In addition, the literal "abc" will
be placed in the poo
String s1="java" // will store in string pool
String s2=new String("java"); //will store in heap
so s1==s2 results in false.
if You want s2 also in pool then u have to call s2.intern(). After that s1==s2 results in true.

understanding the difference between java.lang.String s = new String("hello") and String hold = "hello" [duplicate]

This question already has answers here:
What is the difference between "text" and new String("text")?
(13 answers)
Closed 9 years ago.
I came across this code and got a bit confused
java.lang.String s = new String("hello");
Im not sure what variable s is being initialized as java.lang.String , and what is the purpose of this vs String hold = "hello". I tried to look through some some documentation but could not find anything.
This is really bad programming style
java.lang.String s = new String("hello");
Remember that all classes in java.lang are imported automatically. If you have a class called String in the same package, it will also be imported but shadow the java.lang.String class. That might be a reason to fully qualify the type like
java.lang.String s;
But in this case, you could only ever assign a java.lang.String reference to it since that class is final and therefore cannot be extended. The conventional thing to do would be
java.lang.String s = new java.lang.String("hello");
If you were asking about
java.lang.String s = new String("hello");
vs
java.lang.String s = "hello";
then check out the other answers or the duplicate.
Doing this:
String s = "hello";
is better than doing this:
String s = new String("hello");
The second method creates a string object when you do "hello", passes it to the String constructor, and then creates another identical String object. The first method only creates one object.
Ok you need to know about constants pool (String literal pool)
When you do
String s = "hello";
you are actually setting up the variable in the constant pool
where as when you do
String s = new String("hello");
it creates a separate object in the constant pool.
read more about it here
http://docs.oracle.com/cd/E13150_01/jrockit_jvm/jrockit/geninfo/diagnos/garbage_collect.html
First thing you must look about is the immutable feature of String in java.
http://javarevisited.blogspot.in/2013/03/how-to-create-immutable-class-object-java-example-tutorial.html
String hold = "hello" uses the immutable nature of the string. So when you do,
String hold2 = "hello"
both hold and hold2 refer to the same instance of "hello" string from the string pool. It means both refer to the same memory location.
But with
String hold2 = new String("hello");
there is a new string "hello" at a new location and hold and hold2 objects refer to different memory locations.
The first thing you should know is that Strings in java are immutable read THIS. Next when you do String s = "hello" behind the scene what happens is that compiler looks into the String Pool (a place where strings are saved in java) and checks if there is a hello string already there. If it is, it points reference s to same string object and returns(Read THIS). Now if you do String hold2 = new String("hello"); none of the above mentioned things happens. Even if you have hello string in String Pool it would still create a new string hello and point reference hold2 to it.

String is immutable. What exactly is the meaning? [duplicate]

This question already has answers here:
Immutability of Strings in Java
(26 answers)
Closed 7 years ago.
I wrote the following code on immutable Strings.
public class ImmutableStrings {
public static void main(String[] args) {
testmethod();
}
private static void testmethod() {
String a = "a";
System.out.println("a 1-->" + a);
a = "ty";
System.out.println("a 2-->" + a);
}
}
Output:
a 1-->a
a 2-->ty
Here the value of variable a has been changed (while many say that contents of the immutable objects cannot be changed). But what exactly does one mean by saying String is immutable? Could you please clarify this topic for me?
source : https://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
Before proceeding further with the fuss of immutability, let's just take a look into the String class and its functionality a little before coming to any conclusion.
This is how String works:
String str = "knowledge";
This, as usual, creates a string containing "knowledge" and assigns it a reference str. Simple enough? Lets perform some more functions:
String s = str; // assigns a new reference to the same string "knowledge"
Lets see how the below statement works:
str = str.concat(" base");
This appends a string " base" to str. But wait, how is this possible, since String objects are immutable? Well to your surprise, it is.
When the above statement is executed, the VM takes the value of String str, i.e. "knowledge" and appends " base", giving us the value "knowledge base". Now, since Strings are immutable, the VM can't assign this value to str, so it creates a new String object, gives it a value "knowledge base", and gives it a reference str.
An important point to note here is that, while the String object is immutable, its reference variable is not. So that's why, in the above example, the reference was made to refer to a newly formed String object.
At this point in the example above, we have two String objects: the first one we created with value "knowledge", pointed to by s, and the second one "knowledge base", pointed to by str. But, technically, we have three String objects, the third one being the literal "base" in the concat statement.
Important Facts about String and Memory usage
What if we didn't have another reference s to "knowledge"? We would have lost that String. However, it still would have existed, but would be considered lost due to having no references.
Look at one more example below
String s1 = "java";
s1.concat(" rules");
System.out.println("s1 refers to "+s1); // Yes, s1 still refers to "java"
What's happening:
The first line is pretty straightforward: create a new String "java" and refer s1 to it.
Next, the VM creates another new String "java rules", but nothing
refers to it. So, the second String is instantly lost. We can't reach
it.
The reference variable s1 still refers to the original String "java".
Almost every method, applied to a String object in order to modify it, creates new String object. So, where do these String objects go? Well, these exist in memory, and one of the key goals of any programming language is to make efficient use of memory.
As applications grow, it's very common for String literals to occupy large area of memory, which can even cause redundancy. So, in order to make Java more efficient, the JVM sets aside a special area of memory called the "String constant pool".
When the compiler sees a String literal, it looks for the String in the pool. If a match is found, the reference to the new literal is directed to the existing String and no new String object is created. The existing String simply has one more reference. Here comes the point of making String objects immutable:
In the String constant pool, a String object is likely to have one or many references. If several references point to same String without even knowing it, it would be bad if one of the references modified that String value. That's why String objects are immutable.
Well, now you could say, what if someone overrides the functionality of String class? That's the reason that the String class is marked final so that nobody can override the behavior of its methods.
String is immutable means that you cannot change the object itself, but you can change the reference to the object.
When you execute a = "ty", you are actually changing the reference of a to a new object created by the String literal "ty".
Changing an object means to use its methods to change one of its fields (or the fields are public and not final, so that they can be updated from outside without accessing them via methods), for example:
Foo x = new Foo("the field");
x.setField("a new field");
System.out.println(x.getField()); // prints "a new field"
While in an immutable class (declared as final, to prevent modification via inheritance)(its methods cannot modify its fields, and also the fields are always private and recommended to be final), for example String, you cannot change the current String but you can return a new String, i.e:
String s = "some text";
s.substring(0,4);
System.out.println(s); // still printing "some text"
String a = s.substring(0,4);
System.out.println(a); // prints "some"
You're changing what a refers to. Try this:
String a="a";
System.out.println("a 1-->"+a);
String b=a;
a="ty";
System.out.println("a 2-->"+a);
System.out.println("b -->"+b);
You will see that the object to which a and then b refers has not changed.
If you want to prevent your code from changing which object a refers to, try:
final String a="a";
A string is a char[] containing a series of UTF-16 code units, an int offset into that array, and an int length.
For example.
String s
It creates space for a string reference. Assigning copies references around but does not modify the objects to which those references refer.
You should also be aware that
new String(s)
doesn't really do anything useful. It merely creates another instance backed by the same array, offset, and length as s. There is very rarely a reason to do this so it is considered bad practice by most Java programmers.
Java double quoted strings like "my string" are really references to interned String instances so "bar" is a reference to the same String instance regardless of how many times it appears in your code.
The "hello" creates one instance that is pooled, and the new String(...) creates a non-pooled instance. Try System.out.println(("hello" == "hello") + "," + (new String("hello") == "hello") + "," + (new String("hello") == new String("hello"))); and you should see true,false,false
immutable means you can't not change the value of the same referance.every time you required to create new referance means new memory location.
ex:
String str="abc";
str="bcd";
here, in the above code ,in the memory there are 2 blocks for storing the value.the first for value "abc" and second for "bcd".the second value is not replace to first value.
this is call the immutable.
In your example, the variable a is just a reference to an instance of a string object. When you say a = "ty", you are not actually changing the string object, but rather pointing the reference at an entirely different instance of the string class.
see here
class ImmutableStrings {
public static void main(String[] args) {
testmethod();
}
private static void testmethod() {
String a="a";
System.out.println("a 1-->"+a);
System.out.println("a 1 address-->"+a.hashCode());
a = "ty";
System.out.println("a 2-->"+a);
System.out.println("a 2 address-->"+a.hashCode());
}
}
output:
a 1-->a
a 1 address-->97
a 2-->ty
a 2 address-->3717
This indicates that whenever you are modifying the content of immutable string object a a new object will be created. i.e you are not allowed to change the content of immutable object. that's why the address are different for both the object.
You are not changing the object in the assignment statement, you replace one immutable object with another one. Object String("a") does not change to String("ty"), it gets discarded, and a reference to ty gets written into a in its stead.
In contrast, StringBuffer represents a mutable object. You can do this:
StringBuffer b = new StringBuffer("Hello");
System.out.writeln(b);
b.append(", world!");
System.out.writeln(b);
Here, you did not re-assign b: it still points to the same object, but the content of that object has changed.
You are actually getting a reference to a new string, the string itself is not being changed as it is immutable. This is relevant.
See
Immutable objects on Wikipedia
An immutable object is an object whose state cannot be modified after it is created.
So a = "ABC" <-- immutable object. "a" holds reference to the object.
And, a = "DEF" <-- another immutable object, "a" holds reference to it now.
Once you assign a string object, that object can not be changed in memory.
In summary, what you did is to change the reference of "a" to a new string object.
String S1="abc";
S1.concat("xyz");
System.out.println("S1 is", + S1);
String S2=S1.concat("def");
System.out.println("S2 is", + S2);
This shows that once a string object is create it cannot be changed. EveryTime you need to create new and put in another String. S
I think the following code clears the difference:
String A = new String("Venugopal");
String B = A;
A = A +"mitul";
System.out.println("A is " + A);
System.out.println("B is " + B);
StringBuffer SA = new StringBuffer("Venugopal");
StringBuffer SB = SA;
SA = SA.append("mitul");
System.out.println("SA is " + SA);
System.out.println("SB is " + SB);
Java String is immutable, String will Store the value in the form of object. so if u assign the value String a="a"; it will create an object and the value is stored in that and again if you are assigning value a="ty" means it will create an another object store the value in that, if you want to understand clearly, check the has code for the String.
Only the reference is changing. First a was referencing to the string "a", and later you changed it to "ty". The string "a" remains the same.
In your example, a refers first to "a", and then to "ty". You're not mutating any String instance; you're just changing which String instance a refers to. For example, this:
String a = "a";
String b = a; // b refers to the same String as a
a = "b"; // a now refers to a different instance
System.out.println(b);
prints "a", because we never mutate the String instance that b points to.
If some object bar holds a reference to a mutable object foo and encapsulates some of its state in mutable aspects of foo's state, that will allow code which can change those aspects of foo to change the corresponding aspects of bar's state without actually touching bar or even knowing of its existence. Generally, this means that objects which encapsulate their own state using mutable objects must ensure that no references to those objects are exposed to any code which might unexpectedly mutate them. By contrast, if bar holds a reference to an object moo and only uses immutable aspects of moo other than identity to encapsulate its state, then bar can freely expose moo to outside code without worrying about anything the outside code might do to it.
Hope the below code would clarify your doubts :
public static void testString() {
String str = "Hello";
System.out.println("Before String Concat: "+str);
str.concat("World");
System.out.println("After String Concat: "+str);
StringBuffer sb = new StringBuffer("Hello");
System.out.println("Before StringBuffer Append: "+sb);
sb.append("World");
System.out.println("After StringBuffer Append: "+sb);
}
Before String Concat: Hello
After String Concat: Hello
Before StringBuffer Append: Hello
After StringBuffer Append: HelloWorld
Probably every answer provided above is right, but my answer is specific to use of hashCode() method, to prove the points like, String... once created can't be modified and modifications will results in new value at different memory location.
public class ImmutabilityTest {
private String changingRef = "TEST_STRING";
public static void main(String a[]) {
ImmutabilityTest dn = new ImmutabilityTest();
System.out.println("ChangingRef for TEST_STRING OLD : "
+ dn.changingRef.hashCode());
dn.changingRef = "NEW_TEST_STRING";
System.out.println("ChangingRef for NEW_TEST_STRING : "
+ dn.changingRef.hashCode());
dn.changingRef = "TEST_STRING";
System.out.println("ChangingRef for TEST_STRING BACK : "
+ dn.changingRef.hashCode());
dn.changingRef = "NEW_TEST_STRING";
System.out.println("ChangingRef for NEW_TEST_STRING BACK : "
+ dn.changingRef.hashCode());
String str = new String("STRING1");
System.out.println("String Class STRING1 : " + str.hashCode());
str = new String("STRING2");
System.out.println("String Class STRING2 : " + str.hashCode());
str = new String("STRING1");
System.out.println("String Class STRING1 BACK : " + str.hashCode());
str = new String("STRING2");
System.out.println("String Class STRING2 BACK : " + str.hashCode());
}
}
OUTPUT
ChangingRef for TEST_STRING OLD : 247540830
ChangingRef for NEW_TEST_STRING : 970356767
ChangingRef for TEST_STRING BACK : 247540830
ChangingRef for NEW_TEST_STRING BACK : 970356767
String Class STRING1 : -1163776448
String Class STRING2 : -1163776447
String Class STRING1 BACK : -1163776448
String Class STRING2 BACK : -1163776447
String is immutable it means that,the content of the String Object can't be change, once it is created. If you want to modify the content then you can go for StringBuffer/StringBuilder instead of String. StringBuffer and StringBuilder are mutable classes.

Java String declaration [duplicate]

This question already has answers here:
What is the difference between "text" and new String("text")?
(13 answers)
Closed 2 years ago.
What is the difference between String str = new String("SOME") and String str="SOME"
Does these declarations gives performance variation.
String str = new String("SOME")
always create a new object on the heap
String str="SOME"
uses the String pool
Try this small example:
String s1 = new String("hello");
String s2 = "hello";
String s3 = "hello";
System.err.println(s1 == s2);
System.err.println(s2 == s3);
To avoid creating unnecesary objects on the heap use the second form.
There is a small difference between both.
Second declaration assignates the reference associated to the constant SOMEto the variable str
First declaration creates a new String having for value the value of the constant SOME and assignates its reference to the variable str.
In the first case, a second String has been created having the same value that SOME which implies more inititialization time. As a consequence, you should avoid it. Furthermore, at compile time, all constants SOMEare transformed into the same instance, which uses far less memory.
As a consequence, always prefer second syntax.
String s1 = "Welcome"; // Does not create a new instance
String s2 = new String("Welcome"); // Creates two objects and one reference variable
First one will create new String object in heap and str will refer it. In addition literal will also be placed in String pool. It means 2 objects will be created and 1 reference variable.
Second option will create String literal in pool only and str will refer it. So only 1 Object will be created and 1 reference. This option will use the instance from String pool always rather than creating new one each time it is executed.

Categories

Resources