If I write this code :
String s = new String("TestString");
I understand how s refers to a string created dynamically. s is not an object in itself, but refers to one.
But I am not able to figure out what this means :
String s = "TestString";
Q1. If it would have been some primitive data type I would understand, but what does this signify for a class type ?
Q2. Is this kind of initialization allowed for user created classes as well ?
Java Level : Beginner
Q1. If it would have been some primitive data type I would understand, but what does this signify for a class type ?
In this case, "TestString" is a string literal. A string literal also serves as a reference to an instance of String. This is per the language specification, §3.10.5. So, in your particular case "TestString" is a reference to an instance of String, and you are assigning that same reference to your variable s.
Now, there are some rather special things about Strings that are referred to by literals. Two string literals with the same value (logically, as strings) always refer to the same instance of String. This is due to the "interning" of string literals.
However, when you say
String s = new String("TestString");
it is still the case that "TestString" refers to an instance of String, in fact to an instance in the string intern pool, but it is not the case that s refers to this same string. Instead, s is initialized to have its value equal to "TestString", but it is in fact a new reference. That is:
String s = new String("TestString");
String t = "TestString";
System.out.println(s == t);
This will print false.
Q2. Is this kind of initialization allowed for user created classes as well ?
No.
String s = "TestString";
Is the normal way to create a String. In fact when you do:
String s = new String("TestString");
What you're doing is create a string first, then passing it as an argument to new String(); So the question is not why the first one exists, but why the second one does. The answer is pretty subtle and you probably won't ever care: The first way creates a String literal that doesn't get garbage collected, and is shared on all the VM. The second one, instead, does. This means, for performance reasons, there are cases when you want to use the second form, like when working with very very large strings.
You can read more about it here:
http://kjetilod.blogspot.com.es/2008/09/string-constructor-considered-useless.html
From the Oracle Documentation:
The most direct way to create a string is to write:
String greeting = "Hello world!";
In this case, "Hello world!" is a string literal—a series of
characters in your code that is enclosed in double quotes. Whenever it
encounters a string literal in your code, the compiler creates a
String object with its value—in this case, Hello world!.
As with any other object, you can create String objects by using the
new keyword and a constructor.
Q1. If it would have been some primitive data type I would understand,
but what does this signify for a class type ?
No, this is special case, in case of String literals, String s = "someString" statement means we are referring to someString which is stored in string constant pool. someString will be an instance of String class but will be stored in string literal pool.
The special thing about String literal pool will be.
String s = "someString";
String s1 = "someString";
Here, s == s1' will returntrue` as they will refer to the same object in string literal pool.
String s2 = new String("someString");
String s3 = new String("someString");
Here, s2 == s3 will return false as both string will be created in non-constant pool memory.
You can find a good tutorial regarding strings here
http://www.thejavageek.com/2013/06/19/the-string-constant-pool/
http://www.thejavageek.com/2013/06/17/string-immutability-in-java/
Q2. Is this kind of initialization allowed for user created classes as
well ?
No we can't.
Related
This question already has answers here:
What is the difference between "text" and new String("text")?
(13 answers)
Closed 2 years ago.
String s="hi";
String s1=new String("hi");
In memory perspective, where are s and s1 stored? whether it is in heap memory or stack.
And s points "hi" and s1 points to memory location of where hi exists?
Please help?
Consider following
String s = "hi";
String s1 = new String("hi");
variable s will refer to the string literal hi that is referenced from String constant pool and if there are some more variables like s2 = "hi", then s and s2 will refer to same object.
String s1 = new String("hi");
This will create a new String at runtime.
In first case ,all the strnig literals are created when class is loaded in JVM
In seconds case, string objects are created when new String() is executed.
You can find a good tutorial about string constant pool at following link
http://www.thejavageek.com/2013/06/19/the-string-constant-pool/
String s="hi";
This statements creates the String object containing "hi" on the String pool.
String s1=new String("hi");
This statement creates a String object containing "hi" on the heap memory and a copy of it on StringPool (if "Hi" is not contained in stringPool).But here, S will point to the object on heap.
At class loading time, all String literals will be placed in pool. When you use new String("hi") an object will be created on heap. s and s1 are reference variables , it should reside in the method call stack ! The string literal "hi" will be handled by the JVM, by creating a String object on the heap, and having a reference to it from the String pool. The new operator merely takes the string object, whose reference is passed in the constructor, and create a new object. It just so happens that the string being passed to the constructor is a literal.
"hi" is a String literal. This gets created once in the String Constant Pool. In Java 7 that's in the Heap with other objects, but prior to that it was created in the Perm-Gen
String s = "hi";
String s1 = new String("hi");
new String("hi") creates a new String object on the heap, separate from the existing one.
s and s1 are references to the two separate objects. References themselves actually live on the stack, even though they point to objects in the heap.
s and s1 are just references to the strings, therefore they will be stored on the stack, unlike the string instances that are referenced by s and s1. In this case the value that s refers to will be put in the string pool whereas the value refered by s1 won't. Why? because the constructor of a string has been used to make that string. Only literals are pooled, and even if you chose those literals to be concatenations of other literals ( for example, if you have made String s2 = "h" + "i" then s and s2 would point to the same instance of a string that was stored in the string pool).
This leads to a little trap though: because pooled strings point to the same object it is tempting to use == operator instead of equals method to compare strings, which is just dangerous, because there are scenarios where == is the same as equals() but there are a lot more where == will have a different result than the equals() method.
Above answers are correct but shouldn't you use String *s1 = new String("hi") in place ofString s1 = new String("hi") ,as call to new will be returning a pointer to the string object.
I am fairly new to C++. Excuse me, if I am wrong.
PS: I am using the gcc version 4.4.7 20120313 (Red Hat 4.4.7-4) (GCC).
According to me when we create String using literal like String s="hello"
s object will reference the String "hello" that is stored in the String Constant pool.
If we will create the new String using New keyword like String s = new String("hello") then in this case two object is created. object s referenced the another object that is stored in the normal heap area and this object will referenced the String Hello that is stored in the String constant pool.
For more details please follow the link:-http://www.javatpoint.com/java-string
When I define a StringBuffer variable with new, this string is not added to the String pool, right?
Now, when I define another StringBuffer but not with new, I define it as StrPrev.append("XXX") suddenly it is.(or so says my college teacher). Why is that? What makes this string to suddenly become a string-pool string?
When I define a StringBuffer variable with new, this string is not added to the String pool, right?
Creating a StringBuffer does not create a String at all.
Now, when I define another StringBuffer but not with new, I define it as StrPrev.append("XXX") suddenly it is.
This is totally confused:
When you call strBuff.append("XXX") you are NOT defining a new StringBuffer. You are updating the existing StringBuffer that strBuff refers to. Specifically, you are adding extra characters to the end of the buffer.
You only get a new String from the StringBuffer when you call strBuff.toString().
You only add a String to the string pool when you call intern() on the String. And that only adds the string to the pool if there is not already an equal string in the pool.
The String object that represents the literal "XXX" is a member of the string pool. But that happens (i.e. the String is added to the pool) when the class is loaded, not when you execute the append call.
(If you teacher told you that StringBuffer puts strings into the Java string pool, he / she is wrong. But, given your rather garbled description, I suspect that you actually misheard or misunderstood what your teacher really said.)
"XXX" in StrPrev.append("XXX") is a string literal that is interned at class loading time (class loading time of the class that contains the code).
"XXX" is not added to the pool by the StringBuffer.
From the JLS section 3.10.5:
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
From the JLS section 12.5:
Loading of a class or interface that contains a String literal
(§3.10.5) may create a new String object to represent that literal.
(This might not occur if the same String has previously been interned
(§3.10.5).)
buf.append("XXX") followed by buf.toString(), and then returning the string to the pool. With the pool in place, only one StringBuffer object is ever allocated.
Actually your teacher is referring to XXX . which goes to StringPool because all string literals written in java program goes to StringPool while execution...
In java String can be created in 2 ways given below
String foo="Test";
String fooobj=new String("Test");
Everywhere it is mentioned about difference between these 2 ways of creating String. I want to know more about What are appropriate scenario's ,
where we should go for
String foo="Test";
And when to go for
String fooobj=new String("Test"); ?
The short answer: If you're in any doubt, you don't want new String("literal here"). If you need it, you'll know you need it, and why.
The long answer:
Essentially the only time you want to use new String("literal here") is if you want to ensure that the resulting string object is not == any other string object. Literals get interned automatically; strings created via new String("literal here") are not.
So why would you want that? The answer is you almost never would, because String instances are immutable, so you don't care if you're sharing a String instance with something else. Just about the only scenario I can imagine is if you had an API that accepted a String and you wanted to have a flag value other than null, and you wanted to check that flag/marker value via ==, like this:
public static final String MARKER = new String("Marker");
public void someFictionalMethod(String arg) {
if (arg == MARKER) {
// Take action on the marker
}
else {
// Take action on the string
}
}
...and even then I'd tend to find it a bit suspect and would explore other ways to do it.
It is never necessary to create a new String object with
String fooobj = new String("Test");
So, you should never do this. Just write String fooobj = "Test"; instead.
Class String is immutable. That means that the content of a String object cannot be changed after it has been constructed. It's never necessary to create an explicit copy of a string literal.
You should never use new String(). Anytime you create string in this way, new object in memory is created. If you write String s = "aaa", then there is a chance such object was already created in a given JVM, it is stored in string pool and thanks to that your variable will be just reference to that existing object - you safe memory in this way.
When you use the second approach, you actually rely on the first approach to initialize the constructor arguments.
So the question is if you could create the String object via first approach, why you spend extra effort to use the second approach ?
I don't see any scenary to use the second constructor style, so always insist in using the first approach.
There is a subtle differences between String object and string literal.
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 (non-pool) memory, and s will refer to it. In addition, the literal "abc" will be placed in the pool.
Strings are constant; their values cannot be changed after they are created. String buffers support mutable strings. Because String objects are immutable they can be shared. For example:
String str = "abc";
is equivalent to:
String str = new String("abc");
You should avoid the second way to declare a string, for reasons explained into other answers
Java has string pool, due to which objects of string class are immutable.
But my question stands -
What was the need to make String POOL?
Why string class was not kept like other class to hold its own values?
Is internally JVM need some strings or is this a performance benefit. If yes how?
A pool is possible because the strings are immutable. But the immutability of the String hasn't been decided only because of this pool. Immutability has numerous other benefits. BTW, a Double is also immutable, and there is no pool of Doubles.
The need for the String pool is to reduce the memory needed to hold all the String literals (and the interned Strings) a program uses, since these literals have a good chance of being used many times, in many places of the program. Instead of having thousands of copies of the same String literal, you just have thousand references to the same String, which reduces the memory usage.
Note that the String class is not different from other classes: it holds its own char array. It may also share it with other String instances, though, when substring is called.
When we compiler see's that a new String literal has to be created,it first check's the pool for an identical string,if found no new String literal is created,the existing String is referred.
the benifit of making string as immutable was for the security feature. Read below
Why String has been made immutable in Java?
Though, performance is also a reason (assuming you are already aware of the internal String pool maintained for making sure that the same String object is used more than once without having to create/re-claim it those many times), but the main reason why String has been made immutable in Java is 'Security'. Surprised? Let's understand why.
Suppose you need to open a secure file which requires the users to authenticate themselves. Let's say there are two users named 'user1' and 'user2' and they have their own password files 'password1' and 'password2', respectively. Obviously 'user2' should not have access to 'password1' file.
As we know the filenames in Java are specified by using Strings. Even if you create a 'File' object, you pass the name of the file as a String only and that String is maintained inside the File object as one of its members.
Had String been mutable, 'user1' could have logged into using his credentials and then somehow could have managed to change the name of his password filename (a String object) from 'password1' to 'password2' before JVM actually places the native OS system call to open the file. This would have allowed 'user1' to open user2's password file. Understandably it would have resulted into a big security flaw in Java. I understand there are so many 'could have's here, but you would certainly agree that it would have opened a door to allow developers messing up the security of many resources either intentionally or un-intentionally.
With Strings being immutable, JVM can be sure that the filename instance member of the corresponding File object would keep pointing to same unchanged "filename" String object. The 'filename' instance member being a 'final' in the File class can anyway not be modified to point to any other String object specifying any other file than the intended one (i.e., the one which was used to create the File object).
What was the need to make String POOL?
When created, a String object is stored in heap, and the String literal, that is sent in the constructor, is stored in SP. Thats why using String objects is not a good practice. Becused it creates two objects.
String str = new String("stackoverflow");
Above str is saved in heap with the reference str, and String literal from the constructor -"stackoverflow" - is stored in String Pool. And that is bad for performance. Two objects are created.
The flow: Creating a String literal -> JVM looks for the value in the String Pool as to find whether same value exists or not (no object to be returned) -> The value is not find -> The String literal is created as a new object (internally with the new keyword) -> But now is not sent to the heap , it is send instead in String Pool.
The difference consist where the object is created using new keyword. If it is created by the programmer, it send the object in the heap, directly, without delay. If it is created internally it is sent to String Poll. This is done by the method intern(). intern() is invoke internally when declaring a String literal. And this method is searching SP for identical value as to return the reference of an existing String object or/and to send the object to the SP.
When creating a String obj with new, intern() is not invoked and the object is stored in heap. But you can call intern() on String obj's: String str = new String().intern(); now the str object will be stored in SP.
ex:
String s1 = new String("hello").intern();
String s2 = "hello";
System.out.println(s1 == s2); // true , because now s1 is in SP
a quick and confusing question. If Class A and Class B have this inside them:-
String name="SomeName";
and both classes are instantiated, is it true that both instances refer to same memory location of variable "name" say when we do this objA.name or objB.name ? which has value "SomeName" and since String is immutable, several instances of both classes of same JVM use the same variable repeatedly? I read somewhere online that, unless there is
String example=new String("something");
is used, the former declaration always creates one copy and it is used until all its applications are terminated for reclaiming memory.
Note: I see several answers, which one do I count on, can someone conclude. Thank you all for your effort, appreciate it.
Yes, if you create two strings like:
String a = "Hello";
String b = "Hello";
They will be the exact same object. You can test it yourself by doing
System.out.println(a == b);
If they are the same object, then their internal reference to the character array will be exactly the same.
Now, if you did String c = "Hell" + "o";, it would not have the same reference since it would have been (internally) built using StringBuilder.
There is a lot of good information here.
The relevant sections has (Note: The following is copied from that web site):
As mentioned, there are two ways to construct a string: implicit construction by assigning a String literal or explicitly creating a String object via the new operator and constructor. For example,
String s1 = "Hello"; // String literal
String s2 = "Hello"; // String literal
String s3 = s1; // same reference
String s4 = new String("Hello"); // String object
String s5 = new String("Hello"); // String object
Java has designed a special mechanism for keeping the String literals - in a so-called string common pool. If two String literals have the same contents, they will share the same storage locations inside the common pool. This approach is adopted to conserve storage for frequently-used strings. On the other hands, String object created via the new operator are kept in the heap. Each String object in the heap has its own storage just like any other object. There is no sharing of storage in heap even if two String objects have the same contents.
You can use the method equals() of the String class to compare the contents of two Strings. You can use the relational equality operator '==' to compare the references (or pointers) of two objects. Study the following codes:
s1 == s1; // true, same pointer
s1 == s2; // true, s1 and s1 share storage in common pool
s1 == s3; // true, s3 is assigned same pointer as s1
s1.equals(s3); // true, same contents
s1 == s4; // false, different pointers
s1.equals(s4); // true, same contents
s4 == s5; // false, different pointers in heap
s4.equals(s5); // true, same contents
Edit to add: Run this SSCE to test reference equality between two constant strings in to different classes:
class T {
String string = "Hello";
public static void main(String args[]) {
T t = new T();
T2 t2 = new T2();
System.out.println(t.string == t2.string);
}
}
class T2 {
String string = "Hello";
}
prints out true.
If "something" is literally hard-coded into your source code, then the two variables will point to the same in-memory String object.
Per the Java spec, a string literal (one that's defined as a literal in the byte codes) is "interned", so that any reference to that literal will obtain the exact same pointer, even if the reference is to an identical literal in an entirely separate class.
A string constructed at runtime (eg, "abc" + "xyz" or new String("abc")) will not be interned, and so the pointer will generally be unique. (But note that an optimizing compiler may combine "abc" + "xyz" into the single literal "abcxyz", resulting in an interned value.)
the former declaration always creates one copy and it is used until all its applications are terminated for reclaiming memory.
Strings, like other object are reclaimed when a GC is performed and there is no strong reference to it. Even intern'ed Strings can be cleaned up when they are no longer used.
I would add one more detail to all the solutions above. String interning is just an optimization of Java/C# compiler. It's not good to rely on it as it can be turned off in both cases.
It may also behave differently in different compilers/VM's implementations