This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
difference between string object and string literal
Hello,
Foremost, let’s come up with Java facts with String
Strings are immutable
My Question - If Strings are immutable then below statement should have compilation error!
String str = "xyz";
or
String str = new String("xyz");
str = "abc"; //COMPILATION ERROR
or
str = new String("abc"); //COMPILATION ERROR
What is the difference between below instantiation ?
String str = "xyz";
and
String str = new String("xyz");
Amit.
Strings are immutable means you can't do something like str[1] = 'x' i.e you cannot change the content of the string.
This will answer your second question.
Strings are immutable, so you cannot change the contents of a string.
In the following code:
String str = "xyz";
str = "abc";
you're not changing the contents of a String instance, but rather assigning a new String instance to the variable str. That is, if you do:
String str = "xyz";
String otherStr = str;
String str = "abc";
Then otherStr will remain the same. So you're not actually changing the object that str points to.
As for your second question
String str = "xyz";
takes the a String-object with value "xyz" from the String pool, while
String str = new String("xyz");
instantiates a new object.
That is, if you do
String a = "xyz", b = "xyz";
you will have a == b, while if you do
String a = new String("xyz"), b = new String("xyz");
this will not be the case.example
For more information, see:
What is String literal pool?
Questions about Java's String pool
Strings are immutable. String references are not. That's the distinction.
So:
String str = "abc";
str is a variable, referring to an immutable string "abc". Now if I do:
str = "def";
str is still a variable, referring to a different immutable string ("def"). I can change what str points to all I want, str is a variable. I can't change the actual content of any string (because Java's strings are immutable, by design). Whenever you do something that would seem to modify the string (say, toUpperCase), what it's actually doing is creating a new string with a copy of the old string's contents, modified in the way described.
The point of having strings be immutable is that I know that if I have a reference to a string, that string can never change. This is a very useful guarantee when passing strings around. If we didn't have this guarantee, we'd be copying strings all the time just to protect ourselves from someone modifying them. For instance, consider a standard setter function for a name property:
void setName(String n) {
this.name = n;
}
If strings weren't immutable, we'd have to do this:
void setName(String n) {
this.name = new String(n); // Blech, duplication
}
...so that we know our copy of the string won't change in ways we don't expect it to. This would result in a lot of duplication of string data in memory, most of it unnecessary, and so the designers of Java quite intelligently decided that strings would be immutable, and any changes you might want would create a new string rather than modifying the old one in-place. (You can get modify-in-place behavior for those situations that really warrant it by using char[] instead.)
Regarding your separate question about the difference between str = "abc"; and str = new String("abc"), the difference is that the latter (using the constructor) is guaranteed to return a new reference, whereas the former is not. E.g.:
String a = "abc";
String b = "abc";
String c = new String("abc");
a == b (checking whether the references match, not the strings) will be true, because literal strings are interned. a == c is guaranteed to be false, because we used the constructor for c. a.equals(b) and a.equals(c) will both be true, because a, b, and c all refer to equivalent strings.
If Strings are immutable then below
statement should have compilation
error!
You are misunderstanding the immutability concept. Look at Prasoon's answer.
String immutability means you cannot alter the contents inside the string.
String a = "hello";
String b = "hello";
System.out.println(a==b); // returns true.
Here both a and b both string literals refer the same object.
What is the difference between two
instantiations ?
String a = "hello";
String b = "hello";
System.out.println(a==b); // returns true.
Both refer to same String literal.
String a = new String("hello");
String b = new String("hello");
System.out.println(a==b); // returns false.
Two different String Objects are created.
String str = "xyz";
is an internal cached string instance.
String str = new String("xyz");
is a new object not instanciated from the cache
As side fact notice the following behaviour ...
"xyz" == "xyz" evals true
new String("xyz") == new String("xyz") evals false
new String("xyz").equals(new String("xyz")) evals true
notice also that == in Java compares object references.
Related
,the below code :
String str1 = "SachinTendulkar";
String str2 = str1.substring(6, str1.length());
String str3 = "Tendulkar";
the values in str2 and str3 are the same, but they do not refer to the same objects, what is exactly happening, where is str2 object created?
Thanks in advance.
String str2 = str1.substring(6, str1.length());
The above line will create a new Object, however String str3 = "Tendulkar"; is String literal and may reuse an instance from the string constant pool. String literals are by default intern String object and creating a String object using new String is not intern by default.
Now if you create an object with new String("Some String") it will explicitly create a new String object in heap. Now let take a look at String#substring method it returns like below. That means it will create a new String Object every time it successfully executes.
return ((beginIndex == 0) && (endIndex == value.length)) ? this
: new String(value, beginIndex, subLen);
String is the only class that can be instanciated using characters, that means it's exactly as if you wrote
String str2 = new String(str1.substring(6, str1.length()));
So basically str2 is a new instance of the String class, so is str3, they are two different objects.
How do I compare strings by reference like in Java? I know C#'s strings are compared by value with ==.
Object.ReferenceEquals does not work well too because C# assigns the existing address of a string to a new string if its contents already exist within the intern pool.
I've read this post and they suggest this:
Comparing VALUE and REFERENCE of types
string str = "hello";
string str2 = new StringBuilder().Append("he").Append("llo").ToString();
What I want to happen is something to this effect:
string s1 = "a";
string s2 = "a";
Console.WriteLine(s1 == s2); //False
//Or
Console.WriteLine(Object.ReferenceEquals(s1,s2)); //False
However, this is not the case for the 2 strings above. How do I achieve the same effect without using a StringBuilder?
You can use String.Copy to create a new instance:
string s1 = "a";
string s2 = String.Copy(s1);
Console.WriteLine(Object.ReferenceEquals(s1,s2)); //False
You could simply use new:
char[] charArray = new char[3];
charArray[0] = 'a';
charArray[1] = 'b';
charArray[2] = 'c';
string s1 = new string(charArray);
string s2 = new string(charArray);
Console.WriteLine(Object.ReferenceEquals(s1, s2));
Runnable example: https://ideone.com/H1O16q
The reason this works is because new always creates a new instance of the given type without doing any internalization. Every major OOP language behaves this way, as far as I'm aware.
In C# , string is immutable reference type. so, it has similar behaviors as value type (Ex: as your example here). But string builder is purely reference type.
So, you cannot use string to compare reference, but you can use stringbuilder.
StringBuilder p = new StringBuilder("test");
StringBuilder q = new StringBuilder("test");
Console.WriteLine(p == q); //false
This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 6 years ago.
String s1 = "abc";
String s2 = "abc";
String s3 = new String("abc");
String s4 = new String("abc");
if (s1 == s2) is giving true
while (s3 == s4) is giving false.
Can somebody give a detailed explanation onto what is String pool, heap, how many objects are created in each line and how many objects created in total.
Why s3==s4 is giving false?
A detailed explanation will be much appreciated.
When you do new String(...), it is evaluated at runtime and hence creates two different instances and you end up getting s3 == s4 as false. Same thing happens when you use StringBuilder and do something like sb.toString() which is again evaluated at runtime.
For Example,
StringBuilder sb = new StringBuilder();
String foo = sb.append("abc").toString();
String bar = new String("abc");
String foobar = "abc";
Here foo, bar and foobar are all different objects and hence foo == bar or foo == foobar will evaluate to false.
On the other hand s1 == s2 returns true because abc one declared, already exists in the String Pool and in this case both the objects points to the same reference in the pool.
String Class in java is defined in java.lang package and it is exactly that, a class and not a primitive like int or boolean.
Strings are developed to offer operations with many characters ans are commmonly used in almost all the Java applications
Some interesting facts about Java and Strings:
String in immutable and final in Java and in this case JVM uses String Pool to store all the String objects.
What are different ways to create String Object?
We can create String object using new operator like any normal java class or we can use double quotes (literal assignment) to create a String object.
There are too several constructors available in String class to get String from char array, byte array, StringBuffer and StringBuilderetc etc.
To your Question:
When we create a String using double quotes, JVM looks in the String pool to find if any other String is stored with same value. If found, it just returns the reference to that String object else it creates a new String object with given value and stores it in the String pool.
When we use new operator, JVM creates the String object but don’t store it into the String Pool. We can use intern() method to store the String object into String pool or return the reference if there is already a String with equal value present in the pool.
So when you do
String s1 = "abc";
String s2 = "abc";
those are checked in the StringPool and since s1 already exist there, s2 will take the same reference, hence, s1 ==s2 is true.
but when you do:
String s3 = new String("abc");
String s4 = new String("abc");
you are using the new operator, therefore the JVM is not checking if there is an string already in the heap, it will just allocate a new space for s4, so is s3==s4 ??? of course no.
Please take a look at the image below for a more illustrative example.
Is there a difference between these two methods?
public String toString() {
return this.from.toString() + this.to.toString();
}
public String toString() {
return new String(this.from.toString() + this.to.toString());
}
(assuming, of course, that the from.toString() and to.toString() methods are returning Strings).
Basically I'm confused about String handling in Java, because sometimes strings are treated like a primitive type even though they are class instances.
There is no difference in real.
as both of your function has return type String, creating a new String() is just a overhead. it like wrapping a string to again to a string and create a new string in pool which in real has no advantage.
But one major difference in primitive type and String object is that class String always create new string.
String str = "my string";
if "my string" already exists in String pool. then it will use the same string instead of creating new.
This is the reason why when,
String str1= "my string";
String str2 ="my string";
str1==str2? --> will return true
The result of above will be true, because same String object from pool is used.
but when you do,
String str = new String("new string");
Always, a new String object is created, irrespective of a same one already exists in pool or not.
so comparing:
String str1 = new String("new string");
String str2 = new String("new string");
str1==str2 --> will return false
There is a difference, if at some point you previously defined a String "ABC". Java interns strings, so when you don't explicitly state that you want a new object, it will return an object that has the same value. So for example.
String abc = "abc";
// Some code.
return new String("abc"); // This will be a new object.
Whereas if you do this:
String abc = "abc";
// Some code.
return "abc"; // This will be the above object.
This is because it's pointless for the JVM to waste memory with objects of the same value, so it stores them in memory and waits for you to need / use them again!
Which one do you go for?
More often than not the String interning process won't hamper you too much, so you're usually okay going for the former.
The second one has an extra overhead.. In the second method you are initializing the string one more time that the first one ... something like
String s = "something";
return s;
vs
return new(s);
apart from that both will do the exact same task.
return new String(this.from.toString() + this.to.toString());
Above statement will create 2 objects.
1st object is referring to concatenated value of this.from.toString() + this.to.toString(). This doesn't have reference.
2nd object is created because of new operator.
return this.from.toString() + this.to.toString();
This will create 1 object on heap memory area.
Suppose we create a String s as below
String s = new String("Java");
so this above declaration will create a new object as the new operator is encountered.
Suppose in the same program if we declare a new String s1 as below :
String s1 = "Java";
Will this create a new object or will it point to the old object with Java as it is already created with new operator above.
Well, the second line won't create a new object, because you've already used the same string constant in the first line - but s1 and s will still refer to different objects.
The reason the second line won't create a new object is that string constant are pooled - if you use the same string constant multiple times, they're all resolved to the same string. There still has to be a String object allocated at some point, of course - but there'll only be one object for all uses. For example, consider this code:
int x = 0;
for (int i = 0; i < 1000000; i++) {
String text = "Foo";
x += text.length();
}
This will not create a million strings - the value of text will be the same on every iteration of the loop, referring to the same object each time.
But if you deliberately create a new String, that will definitely create a new object - just based on the data in the existing one. So for example:
String a = new String("test");
String b = new String("test");
String x = "test";
String y = "test";
// Deliberately using == rather than equals, to check reference equality
System.out.println(a == b); // false
System.out.println(a == x); // false
System.out.println(x == y); // true
Or to put it another way, the first four lines above are broadly equivalent to:
String literal = "test";
String a = new String(literal);
String b = new String(literal);
String x = literal;
String y = literal;
String myString = new String("Java");
creates two objects.
String myString = "Java";
creates one object.
In order to create a new object we use new keyword, Object cannot be created without using new.
As per the declaration in the first instance a new Object is created but in the second instance you are only declaring a variable with a value.
So its not an Object.
String s1="foo"; literal will be created in StringPool.
String s2="foo"; this time it will check "foo" literal is already available in StringPool or not as now it exist so s2 will refer the same literal as s1.
String s3=new String("foo"); "foo" literal will be created in StringPool first then through string arg constructor String Object will be created i.e "foo" in the heap due to object creation through new operator then s3 will refer it.
When you create a String with literal (e.g. String str = "Hello";) the Object is not created in Heap it will be available in StringPool only, however when you create a String using 'new' operator (e.g. String str = new String("Hello")) then the Object in StringPool is created along with one more object in Heap. So we are creating two objects unnecessarily. So string creating with literal is preferred way.