Best practice curiosity regarding String instantiation [duplicate] - java

This question already has answers here:
Strings are objects in Java, so why don't we use 'new' to create them?
(15 answers)
Closed 9 years ago.
I was reading some advices about best practices in java and I got the following idea which made me curious
Also whenever you want to instantiate a String object, never use its constructor but always instantiate it directly.
For example:
//slow instantiation
String slow = new String("Yet another string object");
//fast instantiation
String fast = "Yet another string object";
Why is this? doesn't the 'fast' call the default string constructor?

When you use new you get a new string object, but if you use string literal then see here:
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. The single copy of each string is called its 'intern' and is
typically looked up by a method of the string class, for example
String.intern() in Java. All compile-time constant strings in Java are
automatically interned using this method.
If you do:
String a = "foo";
String b = "foo";
Then a==b is true !
A String will be created only if it hasn't been interned.
An object will be created in the first time, and it'll be stored in a place called the String constant pool.
But using the new which will create a different object for each string, will output false.
String a = new String("foo");
String b = new String("foo");
Now a==b is false.
So when using literal it is easier to read, plus easier for the compiler to make optimizations. So.. use it when you can.

The JVM maintains a pool of String literals for optimizations. When you create a String using the constructor,
String s1 = new String("foo");
A new String object is created, and the literal "foo" is added to the pool. After this, anytime you use "foo" in your code, the "foo" refers to the item in the pool and a new object is not created. Since String is immutable, this does not create any problems.
So when you create a String using the "shortcut":
String s2 = "foo"
the JVM looks into the pool, if "foo" already exists there, it will make s2 refer to the item in the pool.
This is a major difference with possible performance impacts: The constructor always creates an object, and adds the literal to the pool if it is not already present there. The shortcut refers to the item in the pool and creates a new object only if the liuteral is not in the pool.

Related

Does new String() update the string pool in Java? [duplicate]

This question already has answers here:
Questions about Java's String pool [duplicate]
(7 answers)
Closed last month.
If I write something like this:
String s1 = new String("ABC");
String s2 = "ABC";
In which scenarios does the string pool get updated? The first, second or both?
In the above programming code ,when string pool get updated?
The first statement will update/add to the String pool with "ABC" String literal, but create another object in the heap and the variable s1 will refer the heap object.
The second statement will refer the already created Pool String object.
String s = new String("ABC");
this always create a new String object on the heap and add "ABC" to the pool(if not present).
String s= "ABC";
Whereas this line is called string literal. It checks whether the string pool already has the same string "ABC" or not. If present then s will refer to that object otherwise a new object will be created.
Conclusion: new String() will always create a new object and string literal checks the string pool before creating one.
String s1=new String("ABC");//creates two objects and one reference variable
In your case, JVM will create a new String object in normal(nonpool) Heap memory and the literal "ABC" will be placed in the string constant pool.The variable s1 will refer to the object in Heap(nonpool).
String Constant Pool
String objects created with the new operator do not refer to objects
in the string pool but can be made to using String’s intern() method.
The java.lang.String.intern() returns an interned String, that is, one
that has an entry in the global String literal pool. If the String is
not already in the global String literal pool, then it will be added.
Whenever you use new keyword to create String Object,it will create in Heap and then it will check the String Constant Pool for the same String Literal.If SCP doesn't contain that String literal then Only it will create String literal in the SCP.
Nope. Strings created with the constructor never enter the string pool.
In the example, two separate objects are created. Therefore:
s1 != s2

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 to create a String object using new [duplicate]

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.

How many String objects using new operator [duplicate]

This question already has answers here:
Questions about Java's String pool [duplicate]
(7 answers)
Closed 5 years ago.
When we use new operator to create a String object, I read that two Objects are created one Object is string constant pool and second one is in heap memory.
My question here is We are using new operator hence only one object should be created in Heap. Why then one more object has to be created in String Constant pool. I know Java stores String object whenever we not use new operator to create a String. For eg:
String s = "abc" .
In this case only it will create in String constant pool.
String s2 = new String("abc")
only one object hast to be created in heap and not in Constant pool.
Please explain why I am wrong here.
We are using new operator hence only one object should be created in Heap.
Sure - the new operation only creates one object. But its parameter is a String literal, which already represents an object. Any time you use a String literal, an object was created for that during class loading (unless the same literal was already used elsewhere). This isn't skipped just because you then use the object as a parameter for a new String() operation.
And because of that, the new String() operation is unnecessary most of the time and rarely used.
See http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.28
Compile-time constant expressions of type String are always "interned" so as to share unique instances, using the method String.intern
Thus when you write
String s2 = new String("abc")
The Compile-time constant expression "abc" will be interend.
It will be created two object, one object into pool area and other one in non pool area because you are using new and as well as string literal as a parameter.
String s = new String("abs");
String s2 = new String("abc")
It will create only one object in heap memory. We need to use intern() method of java.lang.String explicitly to make the entry in String pool.
String s = "def".
Two Objects will be created here. When you create using String literal notation of Java, it automatically call intern() method to put that object into String pool, provided it was not present in the pool already.
String in java is Immutable, once created its cannot be changed. also, any string literal will be stored in the string pool for later use whenever the same literal is used again, for example:
String name = "my name"; // one intern object is created in pool
String otherName = "my name"; // the old intern object is reused
System.out.println( name == otherName); // true , the same reference refer to same object
the two reference refer to the same location in the pool.
String name = new String("my name"); // one object is created, no string pool checking
String otherName = new String("my name"); // other object is created, no string pool checking
System.out.println( name == otherName); // false, we have 2 different object
here we have two different String object in memory each of them have its own value.
see this article for more:
http://www.javaranch.com/journal/200409/Journal200409.jsp#a1
form this below line of code will create 3 object in the JVM
String s2 = new String("abc")
for "abc" in String pool memory.
for new operator one object in heap.
one more for s2.
String s2 = new String("abc");
here 1 literal and 1 object will be created.
With new operator 1 String object will be created in heap as "abc" and s2 will refer it, moreover "abc" is string literal also that is passed in String Constructor so it will go in String Constant pool.
literal is consider as object so 2 object will be created here.

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