Why new keyword not needed for String - java

I am new in java.
In java, String is a class.But
we do not have to use new keyword to create an object of class String where as new is used for creating objects for other classes.
I have heard about Wrapper classes like Integer,Double which are similar to this.
But String is not Wrapper,isn't it?
Actually what is happening when i use
String message = "Hai";
??
How it is different from
String message = new String("Hai");
Here is message a reference variable or something else??
Are there other classes which do not require new to create object ??

With the following line you are not creating a new String object in the heap but reusing a string literal (if already available):
String message = "Hai";
"Hai" is a string literal in the string literal pool. Since, strings are immutable, they are reusable so they are pooled in the string literal pool by the JVM. And this is the recommended way, because you are reusing it.
But, with the following you are actually creating a new object (in the heap):
String message = new String("Hai");
new String("Hai") is a new String object. In this case, even if the literal "Hai" was already in the string literal pool, a new object is created. This is not recommended because chances are that you might end with more than one String objects with the same value.
Also see this post: Questions about Java's String pool
Are there other classes which do not require new to create object ??
Actually, you can not create any object in Java without using the keyword new.
e.g.
Integer i = 1;
Does, not mean that the Integer object is created without using new. It's just not required for us to use the new keyword explicitly. But under the hood, if the Integer object with value 1 does not already exist in cache (Integer objects are cached by JVM), new keyword will be used to create it.

The Java language specification allows for representation of a string as a literal. You can consider it a shortcut initialization for a String that has one important side-effect that is different from regular initialization via new
String literals are all interned, which means that they are constant values stored by the Java runtime and can be shared across multiple classes. For example:
class MainClass (
public String test = "hello";
}
class OtherClass {
public String another = "hello";
public OtherClass() {
MainClass main = new MainClass();
System.out.println(main.test == another);
}
}
Would print out "true" since, both String instances actually point to the same object. This would not be the case if you initialize the strings via the new keyword.

String and Integer creation are different.
String s = "Test";
Here the '=' operator is overloaded for string. So is the '+' operator in "some"+"things".
Where as,
Integer i = 2;
Until Java 5.0 this is compile time error; you cant assign primitive to its wrapper. But from Java 5.0 this is called auto-boxing where primitives are auto promoted to their wrappers wherever required.
String h1 = "hi";
will be different from
String h2 = new String("hi");
The reason is that the JVM maintains a string table for all string literals. so there will be an entry in the table for "hi" , say its address is 1000.
But when you explicitly create a string object, new object will be created, say its address is 2000. Now the new object will point to the entry in the string table which is 1000.
Hence when you say
h1 == h2
it compares
1000 == 2000
So it is false

In java
"==" compares the left & right hand sides memory locations(and not the value at that memory location) and therefore in case of
new String("hai")==new String("hai")
it returns false.
In case of "Hai"=="Hai", java doesn't allocate separate memory for same string literal therefore here "==" returns true. You can always use equals method to compare values.

The reason why doesn't recommended because of memory, using new keyword and creating String object, JVM create 2 object between HEAP and SCP, but using just literal is that JVM creating only SCP. That's why we creating String object, just using literal.

Related

If declared string using new keyword and same string be assigned another value using assignment operator what will happen in java

String newString=new String("JAVA");
newString="JAVA8";
WHAT will happen here if we print newString we know output will be JAVA8 only but 2nd line created new object in heap or constant pool.
How its behave internally
In Java Strings are immutable.
What that means is that once a String object is created it cannot be updated.
Also Java has something called Java String Pool, a memory location where Java stores Strings.
To minimize the memory space used by this String Pool, Java performs Interning when a new String literal is create using the following statement.
String s = "apple";
What Interning means is that JVM looks in the String Pool to see if the string literal "apple" exists, if it does it just passes its reference to new variable, no new object is created, if it does not exist it creates a new object passes its reference and also can pass the same reference if another string is created with same value. For Example:
String t= "apple";
If you check if the both strings created above are reference to the same string literal in string pool, you can do that as follows:
System.out.println(s == t); // True
When a string is created using new keyword it always creates a new Object in the String pool, even if the string literal exists in the string pool.
String u = new String("apple");
You can check that the new object is created by following statement:
System.out.println(s == u); // False
System.out.println(t == u); // False
In yoru case the first statement created a new object in String pool and passed its reference. The second line created another object and passed its reference. The first object is still in String pool but not being referenced by any variable and eventually the memory occupied by it will be released by Garbage collection.
Hope this answers your question, you can read about Java String pool to know more.
First, newString is not a String!!!
newString is a reference to an instance of the class String! A C programmer would name it pointer and write String* newString.
With
String newString = new String( "JAVA" );
you declare the variable newString of type "reference to String" and assign the reference to (the address for) the new object, created by a call to the constructor of the class java.lang.String from the compile time constant "JAVA".
newString = "JAVA8";
now assigns the reference to the compile time constant "JAVA8" to that previously created variable. At the same time, the previously reference object gets abandoned (no more references to that object were hold) and therefore it is now ready to be garbage collected.
Most Java implementations do store the compile time constants not on the heap, and strings are usually stored in the string pool. Also it is possible that the call to new String() will never be executed; instead the compiler will directly use the reference to the compile time constant. Or it will be executed and the resulting String object is stored on the Heap, with or without referencing the string value in the string pool.
The details can be found in the Java Language Specification and the JVM Specification for the respective version, and if that says "implementation dependent", in the documentation for the respective JVM/Java implementation.

Object life cycle in java and memory management?

For the below statement in a program, how many objects will be created in heap memory and in the string constant pool?
I need clarity in object creation. Many sources I've read are not elaborating. I am confused when the object gets destroyed.
String a="MAM"+"BCD"+"EFG"+"GFE";
How many objects will be created?
I am looking for good material about the life cycle of objects, methods and classes and how the JVM handles them when they are dynamically changed and modified.
"MAM"+"BCD"+"EFG"+"GFE" is a compile-time constant expression and it compiles into "MAMBCDEFGGFE" string literal. JVM will create an instance of String from this literal when loading the class containing the above code and will put this String into the string pool. Thus String a = "MAM"+"BCD"+"EFG"+"GFE"; does not create any object, see JLS 15.18.1. String Concatenation Operator +
The String object is newly created (§12.5) unless the expression is a compile-time constant expression (§15.28).
It simply assigns a reference to String object in pool to local var a.
Only one object is created.
string s1 = "java";
string s2 = "ja" + "va";
s.o.p(s1==s2);
The statement yields true.
String s1="java";
string s2 = "ja";
String s3 = s2 +"va";
s.o.p(s1==s3);
The statement yields false.
So minimum one apparent should be permanent, then '+' operator generates new string object (in non constant pool using new()).
So, the question you asked does not have one also permanent. This means it creates only one object.
Exactly one object is created and placed in the constant pool, unless it already exists, in which case the existing object is used. The compiler concatenates string constants together, as specified in JLS 3.10.5 and 15.28.
A long string literal can always be broken up into shorter pieces and written as a (possibly parenthesized) expression using the string concatenation operator +
http://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.5
Most answers seem to focus that a) the complete expression is one compile time constant and b) that the line itself does not construct a new object but only a reference to one object.
However noone so far has mentioned, that String itself contains a reference to an internal char[] (which is also in the constant pool).
Summary: There are two objects in the constant pool (String and char[]). The line does neither create nor destroy any object.
And regarding:
I am confused when the object gets destroyed.
No object is destroyed, since stuff in the constant pool will only be destroyed if the class itself would be unloaded. At most you can say, that the reference a will go out of scope eventually.
Only one object will be created since String a will compile into "MAMBCDEFGGFE".
Answers stating a single heap object in your example are correct. However, consider this code:
public class Tester
{
public String a="MAM";
public String b ="BCD";
public String c = "EFG";
public String d ="GFE";
public Tester()
{
String abcd = a + b + c + d;
}
}
In this example, there are 7 strings being created. a,b,c and d are not compiled into a single constant - they are members. 1 string is then created for each + operator - semantically speaking, + is a concatenation but logically it is creating a new string in memory. The first 2 operator strings are discarded immediately and are now eligible for garbage collection but the memory churn still occurs.
Technically there in an 8th object. The instance of Tester.
Edit: This has been proved to be nonsense in the comments

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.

Java immutable strings confusion

If Strings are immutable in Java, then how can we write as:
String s = new String();
s = s + "abc";
Strings are immutable.
That means that an instance of String cannot change.
You're changing the s variable to refer to a different (but still immutable) String instance.
Your string variable is NOT the string. It's a REFERENCE to an instance of String.
See for yourself:
String str = "Test String";
System.out.println( System.identityHashCode(str) ); // INSTANCE ID of the string
str = str + "Another value";
System.out.println( System.identityHashCode(str) ); // Whoa, it's a different string!
The instances the str variable points to are individually immutable, BUT the variable can be pointed to any instance of String you want.
If you don't want it to be possible to reassign str to point to a different string instance, declare it final:
final String str = "Test String";
System.out.println( System.identityHashCode(str) ); // INSTANCE ID of the string
str = str + "Another value"; // BREAKS HORRIBLY
The first answer is absolutely correct. You should mark it as answered.
s = s+"abc" does not append to the s object. it creates a new string that contains the characters from the s object (of which there are none) and "abc".
if string were mutable. it would have methods like append() and other such mutating methods that are on StringBuilder and StringBuffer.
Effective Java by Josh Bloch has excellent discussion on immutable objects and their value.
Immutable Classes are those whose methods can change their fields, for example:
Foo f = new Foo("a");
f.setField("b"); // Now, you are changing the field of class Foo
but in immutable classes, e.g. String, you cannot change the object once you create it, but of course, you can reassign the reference to another object. For example:
String s = "Hello";
s.substring(0,1); // s is still "Hello"
s = s.substring(0,1); // s is now referring to another object whose value is "H"
String s = new String();
Creates a new, immutable, empty string, variable "s" references it.
s = s+"abc";
Creates a new, immutable, string; the concatenation of the empty string and "abc", variable "s" now references this new object.
Just to clarify, when you say s = s+"abc";
That means, create a new String instance (which is composed of s and "abc") then assign that new String instance to s. So the new reference in s is different from the old.
Remember, a variable is effectively a reference to an object at some specific memory location. The object at that location stays at that location, even if you change the variable to refer to a new object at a different location.
String s = new String();
An empty String object ("") is created. And the variable s refers to that object.
s = s + "abc";
"abc" is a string literal (which is nothing but a String object, which is implicitly created and kept in a pool of strings) so that it can be reused (since strings are immutable and thus are constant). But when you do new String() is totally different because you are explicitly creating the object so does not end up in the pool. You can throw is in the pool by something called interning.
So, s + "abc" since at this point concatenation of and empty string ("") and "abc" does not really create a new String object because the end result is "abc" which is already in the pool. So, finally the variable s will refer to the literal "abc" in the pool.
I believe you are all making this much more complicated than it needs to be, and that simply confuses people who are trying to learn!
The primary benefit of making an object immutable in Java is that it can be passed by reference (e.g. to another method or assigned using the assignment operator) without having to worry about downstream changes to the object causing issues in the current method or context. (This is very different than any conversation about the thread safety of an object.)
To illustrate, create an application that passes a String as a parameter to a separate method, and modify the String in that method. Print the String at the end of the called method and then after control returns to the calling method. The Strings will have different values, and that's because they point to different memory locations, a direct result of "changing" the immutable String (creating a new pointer and pointing it to a new value behind the scenes). Then create an application that does the same things except with StringBuffer, which is not immutable. (For example, you can append to the StringBuffer to modify it.) The printed StringBuffers will have the same values, and that is because it is (a) being passed by reference, as Java does with all objects passed to methods as parameters and (b) mutable.
I hope this helps folks who are reading this thread and trying to learn!

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