Why to create a String object using new [duplicate] - java

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Java Strings: “String s = new String(”silly“);”
What is the purpose of the expression “new String(…)” in Java?
There are two ways to create a String object:
1) using literal as in String s ="hello" (creates one object)
2) using new as in String s = new String("hello") (creates two objects)
I was wondering why do ever I need to go for 2) approach?

If you create a string with new, then you get a different String reference. This can avoid creepy behaviour:
String s = "hello";
String t = "hello";
String u = new String("hello");
System.out.println(s==t);
System.out.println(t==u);
prints true, false. I can't really think of a real bit of software where I'd use this. But in a sense it is 'safer' to create new references, so that == doesn't surprise us.

The basic difference between them is memory allocation.
First option i.e
String s1 = "hello";
When you use this s1 is called as a string literal and memory for s1 is allocated at compile time.
But in 2nd case
String s2 = new String("hello");
In this case s2 is called as an object of String representing hello
When you tries to create two string literal using the first case, only one memory is referenced by those two literals. I mean String literals are working with a concept of string pool. when you create a 2nd string literal with same content, instead of allocating a new space compiler will return the same reference. Hence you will get true when you compare those two literals using == operator.
But in the 2nd case each time JVM will create a new object for each. and you have to compare their contents using equals() method but not with == operator.
If you want to create a new string object using 2nd case and also you don't want a new object, then you can use intern() method to get the same object.
String s = "hello";
String s1 = new String("hello").intern();
System.out.println(s == s1);
In this case instead of creating a new object, JVM will return the same reference s. So the output will be true

The only mentally sane occasion where new String("foo") should be used are unit-tests. You can make sure that the code does not use == for string comparisons but the proper .equals() method.

The second approach is just a possibility. Actually is never used (by most of developers). The first one is a less and more convenient version of the latter, no reasons to use the second way.
PS. The second just creates a different link to the literal. Technically they will re-use the same char array. The only difference is the reference will be different (i.e. == will give false, but NEVER use == for string comparison).

This can be understood as a constructor per copy. They are very used in C++. The net effect is having a duplicate of the object passed as a parameter, in this case, a String.

Related

Java String == operator with String Literal [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 3 years ago.
Why does this return true?
This seems a little odd since I have two Strings which are separate objects but are said to be aliases of each other.
public boolean stringEquals() {
String tmp1 = "hello";
String tmp2 = "hello";
return tmp1==tmp2;
}
String literals are interned by the JVM, so their reference will be the same.
In other words, each String literal used will be stored exactly once, hence their object will be similar. See
Taken from here: https://www.geeksforgeeks.org/interning-of-string/
The == operator compares the reference of the 2 objects and not their values. So unless we use .equals() we must expect to see false as these are 2 separate objects.
But this special case happens with strings. In Java Strings are immutable. Meaning their value cannot change. JVM uses this property to optimize memory. The strings in Java are stored in a separate space in memory called String Pool. Since these 2 strings are the same and that they are immutable, JVM stores "hello" in the pool and reuses the same reference for both objects. This is safe as strings are immutable. ( If you assign it something else later in code, it would create a new value elsewhere in pool and reference to it).
At the same time it is interesting to note that this isn't the case when using constructor. If we use the constructor to construct a new string, it always creates a separate object with unique reference regardless of whether the value is same or not.
String a = new String("Hello");
String b = new String("Hello");
return a==b;
Would return false.
The string pool concept applies only when using string literals without the constructor.

Semantics of “==” operator in Java [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 9 years ago.
I was wondering: Why does this code result in false?
Coz == operator should return true when it's the same memory point.
public static void main(String[] args) {
String a = new String("hello");
System.out.println(a == "hello");
}
Can you describe why this happens.
Java compares references when you compare (==) objects. Since you create two new objects, they do have different addresses in memory regardless of their content.
String literals are created on what is called: Pool Memory.
However, when one creates a String with explicitly new keyword, he actually creates a new String object, independent of the pool memory's one. Meaning that both references are not the same at all.
In your sample, you could solve the case by both ways:
_ use java.lang.String.intern method: placing your explicitly created String into the pool memory.
_ use only literals to create/reuse String.
For information, Pool Memory was created in order to avoid some useless creation of common/redundant literal Strings, thus optimizing memory space.
Similar concept exists for Integer: Integer caching in Java
This happens because there are two String objects here - first is the literal and the other is the one created with new String. When you create explicitly a new String object it the String from pool is not reused.
It is well described in details http://theopentutorials.com/tutorials/java/strings/string-literal-pool/
The command String a = new String("hello"); creates a String object in the non-pool part of the memory, and then a refers to it. And then "hello" is placed in the String pool. Whereas while comparing, a == "hello" the "hello", is in the String pool. So, the reference of both the objects are different, although the content of both the objects is same. Had to declared a, in the following manner, the comparison would had returned true
String a = "hello";

Please explain intern() method functionality [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
When should we use intern method of String?
what is string interning?
Please explain the inner workings of the following code:
System.out.println(new String("ABC").intern()==new String("ABC").intern());
In the above code it prints "true". But according java rules, in the case of the new operator, it always creates a new object. object.intern() method also creates an object in the string pool. So my question is, in the above code how many objects are created.
According to me, 3 new objects will created. One goes to String pool, and two anonymous objects will be created by the new operator. But i am not sure.
If i am wrong please explain.
Assuming no cleverness in the optimizer, two objects are created. (A smart enough optimizer could optimize this to just an unconditional true, in which case no objects are created.)
tl;dr version: You were almost right with your answer of 3, except that the string that goes into the String pool is not generated as part of this statement; it's already created.
First, let's get the "ABC" literal out of the way. It's represented in the runtime as a String object, but that lives in pergen and was created once in the whole life of the JVM. If this is the first class that uses that string literal, it was created at class load time (see JLS 12.5, which states that the String was created when the class was loaded, unless it previously existed).
So, the first new String("ABC") creates one String, which simply copies the reference (but does not create a new object) to the chars array and hash from the String that represents the "ABC" literal (which, again, is not created as part of this line). The .intern() method then looks to see whether an equal String is already in permgen. It is (it's just the String that represents the literal to begin with), so that's what that function returns. So, new String("ABC").intern() == "ABC". See JLS 3.10.5, and in particular:
Moreover, a string literal always refers to the same instance of class String. This is because string literals - or, more generally, strings that are the values of constant expressions (§15.28) - are "interned" so as to share unique instances, using the method String.intern.
The same thing exactly happens with the second occurrence of new String("ABC").intern(). And, since both intern() method return the same object as the "ABC" literal, they represent the same value.
Breaking it down a bit:
String a = new String("ABC"); // a != "ABC"
String aInterned = a.intern(); // aInterned == "ABC"
String b = new String("ABC"); // b != "ABC"
String bInterned = b.intern(); // bInterned == "ABC"
System.out.println(new String("ABC").intern()==new String("ABC").intern());
// ... is equivalent to...
System.out.println(aInterned == bInterned); // ...which is equivalent to...
System.out.println("ABC" == "ABC"); // ...which is always true.
When you call intern() method, jvm will check if the given string is there, in string pool or not. If it is there, it will return a reference to that, otherwise it will create a new string in pool and return reference to that.
In your case : System.out.println(new String("ABC").intern()==new String("ABC").intern());
The first new String("ABC").intern() will create a string "ABC" in pool.When you call new String("ABC").intern() second time, jvm will return the reference to previously created string.That is the reason you are getting true when comparing both(btn are pointing to same reference).
I believe you are right, as new operation create a new object so there are 2 anonymous objects and intern() creates a new string in the string pool only if it is not already and returns it's reference

Why should I not instantiate a string object with a constructor?

In Java, apparently, String s = "foo" is preferred over String s = new String("foo").
Why? Isn't a new string object created in both cases? Why would the first case preclude calling a constructor?
Why?
Because the second approach results in two string objects (the original due to the string literal, plus an explicit copy).
The first case is a string literal, simply a shorthand the language offers you to create a string. The String class constructor still gets called, just not explicitly, which means less typing and less code clutter.
The second case takes the String object already created by the literal and passes it to a constructor, which copies the content to create a new, separate String object. The literal will still be around because literals are interned.
There is rarely a point to using the String constructor (pretty much only when you've created a substring of a very large string and want to release the memory used by the rest of the string, because substrings by default use the same underlying char array as the original string, just with a different offset and length.
I don't think it's preferable. I assume the only "benefit" you get is that if you wrongfully use the "==" operator rather than the equals method, have two different instances of a string will fail faster which will prompt you to fix your code. (the == operator may "succeed" and fail unpredictably)
Unless of course your code requires you to construct two different instances for whatever reason
Why? Isn't a new string object created in both cases?
No, the initial form being a string literal will be interned such that only one instance is created:
String s = "foo";
String s2 = "foo";
s == s2 => true

what is the advantage of string object as compared to string literal

i want to know where to use string object(in which scenario in my java code).
ok i understood the diff btwn string literal and string object, but i want to know that since java has given us the power to make string object, there must be some reason, at some point string object creation would be useful. so i want to know in which scenario can we prefer string object in place of string literal.
In most situations, you should use String literals to avoid creating unnecessary objects. This is actually Item 5: Avoid creating unnecessary objects of Effective Java:
Item 5: Avoid creating unnecessary objects
It is often appropriate to reuse a
single object instead of creating a
new functionally equivalent object
each time it is needed. Reuse can be
both faster and more stylish. An
object can always be reused if it is
immutable (Item 15). As an extreme
example of what not to do, consider
this statement:
String s = new String("stringette"); // DON'T DO THIS!
The statement creates a new String
instance each time it is executed, and
none of those object creations is
necessary. The argument to the String
constructor ("stringette") is itself a
String instance, functionally
identical to all of the objects
created by the constructor. If this
usage occurs in a loop or in a
frequently invoked method, millions of
String instances can be created
needlessly. The improved version is
simply the following:
String s = "stringette";
This version uses a single String
instance, rather than creating a new
one each time it is executed.
Furthermore, it is guaranteed that the
object will be reused by any other
code running in the same virtual
machine that happens to con- tain the
same string literal [JLS, 3.10.5]
There is however one situation where you want to use the new String(String) constructor: when you want to force a substring to copy to a new underlying character array like in:
String tiny = new String(huge.substring(0, 10));
This will allow the big underlying char[] from the original huge String to be recycled by the GC.
Don't use a new String object if you know what the string is. For example:
String str = new String("foo"); // don't do this
You are thus creating an unnecessary object - once you have a String object created from the literal, and then you create another one, taking the first one as constructor argument.
Contrary to your question, there is a DISADVANTAGE of using a String object compared to String literal.
When you declare a String literal, String s = "foo", the compiler will check for an existing "foo" object on the heap and assign 's' to already existing "foo".
However, if you create a String object, String s = new String("foo"), an entirely new object will be created on the heap (even if there is already an existing "foo"). Strings being immutable this is totally unnecessary.
Here is good reference: http://www.javaranch.com/journal/200409/ScjpTipLine-StringsLiterally.html
String a = "ABC";
String b = new String("ABC");
String c = "ABC";
a == b // false
a == c // true
a.equals(b) // true
a.equals(c) // true
The point is that a & c point to the same "ABC" object (JVM magic). Using "new String" creates a new object each time. IMO, using string object is a disadvantage, not an advantage. However, as another poster said, string object is useful for converting byte[], char[], StringBuffer - if you need to do that.
String literals are converted to String objects, and as others pointed out, creating explicit String objects is unnecessary and inperformant, as it defeats String pooling.
However, there is one situation where you want to create new Strings explicitly: If you use just a small part of a very long String. String.substring() prevents the original String from getting GC'd, so you can save memory when you write
String s = new String(veryLongString.substring(1,3));
instead of
String s = veryLongString.substring(1,3);
literal strings are objects created in a String Pool and if they have the same value, they are referencing to the same object.
System.out.println("abc"=="abc"); // the output is true
Meanwhile, string object are real objects in memory and if they have the same value, there's no guarantee that they are referencing to the same object.
String a = new String("abc");
String b = new String("abc");
System.out.println(a==b); // the output is false

Categories

Resources