Java String instantiation and assignment atomicity [duplicate] - java

This question already has answers here:
Is String s = "foobar" atomic?
(3 answers)
Closed 7 years ago.
This is related to Is String s = "foobar" atomic? . Im a bit confused by the answer there... Assignments are atomic, thats fine. But if we have
String s = "s";
Wouldn't the steps to execute this line be
1 - assign location of a new String instance to reference s (so its effectively not null, even though constructor for of a new String did not yet run)
2 - run constructor?
So, only time this assignment should happen atomically is if "s" is interned?
Isnt this exactly how reads of partially constructed objects happens?
Not a duplicate - my question is not whether assignment is atomic. My question is what if "s" is not yet interned (effectively does not exist at time of assignment) and if its possible.

Yes, it is an atomic operation.
Maybe this will help (JLS):
Compile-time constant expressions of type String are always "interned" so as to share unique instances, using the method String.intern.
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.
So I am not sure the String constructor is called here.

Related

In Java, when we print a string literal on to the terminal, does this string literal also be stored in the string pool?

I am aware that when we initialize a string literal to a variable this literal will be stored in the string pool by the JVM. Consider the piece of code below.
System.out.println("This is a string literal");
Does the string literal within the quotes also be stored in the string pool even if I don't initialize it to a variable?
I will preface this answer by saying that there is little practical use in gaining a deep understanding of the Java string pool. From a practical perspective, you just need to remember two things:
Don't use == to compare strings. Use equals, compareTo, or equivalent methods.
Don't use explicit String.intern calls in your code. If you want to avoid potential problems with duplicate strings, enable the string de-duplication feature that is available in modern Java GCs.
I am aware that when we initialize a string literal either using the 'new' keyword or not, this literal will be stored in the string pool by the JVM.
This is garbled.
Firstly, you don't "initialize" a string literal. You initialize a variable.
String hi = "hello"; // This initializes the variable `hi`.
Secondly you typically don't / shouldn't use a string literal with new.
String hi = new String("hello"); // This is bad. You should write this as above.
The normal use-case for creating a string using new is something like this:
String hi = new String(arrayOfCharacters, offset, count);
In fact, creation and interning of the String object that corresponds to a string literal, happens either at the first time that the literal is used in an expression or at an earlier time. The precise details (i.e. when it happens) are unspecified and (I understand) version dependent.
The first usage might be in a variable initialization, or it might be in something else; e.g. a method call.
So to your question:
Consider the piece of code below:
System.out.println("This is a string literal");
Does the string literal within the quotes also be stored in the string pool even if I do not initialize it?
Yes, it does. If that was the first time the literal was used, the code above may be the trigger for this to happen. But it could have happened previously; e.g. if the above code was run earlier.
As a followup, you asked:
Why does the String Pool collect string literals which are not stored in a variable and just displayed in the console?
Because the JLS 3.10.5 requires that the String objects which correspond to string literals are interned:
"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 (§12.5)."
And you asked:
The Presence of the String Pool help optimize the program. By storing literals as such (which is actually not required because it is just to be displayed in the console), isn't it the case that it goes against its whole purpose (which is optimization)?
The original idea for interning and the string pool was to save memory. That made sense 25 years ago when the Java language was designed and originally specified. These days even a low-end Android phone has 1GB of RAM, and interning of string literals to save a few thousand bytes is kind of pointless. Except that the JLS says that this must happen.
But the answer is No, it doesn't go against the (original) purpose. This statement:
System.out.println("This is a string literal");
could be executed many times. You don't want / need to create a new String object for the literal each time that you execute it. The thing is that the JVM doesn't know what is going to happen.
Anyway, the interning must happen because that is what the spec says.

how am i able to change value of same String? [duplicate]

This question already has answers here:
Java String Immutability and Using same string value to create a new string
(4 answers)
Closed 7 years ago.
i know Strings are immutable in java and i just read some theory about it
Once a String is declared it cannot be changed . i declared a String and changed it's value just by appending some value to it . it should not have happened
String s = "amol";
s = s + "abc";
System.out.println(s); //output is amolabc
The String s didn't get changed. When you did s + "abc", it created a new String object with the result of the operation.
You need to understand the concept of String Pool in Java. Please go through the link
http://www.javaranch.com/journal/200409/ScjpTipLine-StringsLiterally.html
You are right that Strings are immutable. Here, You didn't change the String s. All distinct Strings are stored in the Heap Memory. So, all the variables (say 10 variables ) containing the same String (say "Hello" ) will occupy only 5 bytes of memory. They all will point to the same location. Separate instances will not be stored for each of those variables.
Here, when you write s = s + "abc", a new string "amolabc" is created in the heap,and now the variable s just points to the new string in the heap. You didn't modify the value of "amol". You just made a new String.
The meaning of immutable is not like you thought to be.Being immutable guarantees that hashcode will always the same, so that it can be cashed without worrying the changes.That means, there is no need to calculate hashcode every time it is used.
here you are appending another string value to it,which can be done.But you cannot concatenate with another string.
By appending it is creating another string.
Refer here

Java String intToStr = "" + 5; Why can't I do this? [duplicate]

This question already has answers here:
String valueOf vs concatenation with empty string
(10 answers)
Closed 7 years ago.
I've had a few people tell me that things like this are super lazy:
int val = 5;
System.out.println("" + val);
String myStr = "" + val;
Why is this better than String.valueOf(val)? Isn't it doing the exact same thing under the hood?
It's not really "better", just shorter, making it easier to read and type. There is (virtually) no ther difference, even though a real purist might, probably, say, this is actually worse, because (at least, in the absence of optimization), this creates an intermediate StringBuilder object, that is then appended a character before being converted into a String, so, this may be spending more ticks, than .valueOf.
From JLS:
An implementation may choose to perform conversion and concatenation in one step to avoid creating and then discarding an intermediate String object. To increase the performance of repeated string concatenation, a Java compiler may use the StringBuffer class or a similar technique to reduce the number of intermediate String objects that are created by evaluation of an expression.
For primitive types, an implementation may also optimize away the creation of a wrapper object by converting directly from a primitive type to a string.

Why DOES == sometimes work on Strings in Java? [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 7 years ago.
I have the following code:
Circle c1 = new Circle();
Circle c2 = new Circle();
System.out.println(c1 == c2);
Which outputs False, as expected. This is because c1 and c2 are reference types and "==" checks if they refer to the same type (which they don't).
However, I recently tried this:
String a = "hello";
String b = "hello";
System.out.println(a == b);
Which for some reason outputs True. Why is this? String is a reference type and a and b refer to different memory locations. I was always taught that you need to use .equals() for this to work, which this does not!
See: https://ideone.com/CyjE49
UPDATE
THIS IS NOT A DUPLICATE!
I know the proper way to compare strings is using .eqauls()
UPDATE 2
This question may have an answer in: How do I compare strings in Java?, but the question there wasn't asking what I am asking and the answer just went in more detail than required.
Therefore searching with my same question (on Google or otherwise) means users won't be sent to that question or may dismiss it entirely due to the title of the question. Therefore it may be a good idea to keep this up for benefit of other users!
Because string literals are intern'd, identical literals refer to the same object. Therefore, checking for reference equality between them will necessarily return true.
From the Java Language Specification (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, using the method String.intern.
In practice, the compiler will pool the string literals "early" and store only one copy in the compiled .class file. However, identical string literals from separate class files will still compare equal using == since the literals are still intern'd when the classes are loaded.
If, on the other hand, we properly apply your example with Circle to String, we would have:
String a = new String("hello");
String b = new String("hello");
System.out.println(a == b); // will print false!
In this case we explicitly create new objects, so they cannot be equal references.
Any string constructed by means other than a literal or other constant string expression will also not necessarily compare reference-equal with an identical string. For example:
String a = "hello";
String b = "hello";
System.out.println(a.substring(0,3) == b.substring(0,3)); // may print false!
String interning. Since both a and b are constants with the same value, the compiler takes advantage of the String's immutability to have both variables refer to the same string and thus save space. Therefore == returns True, since they're effectively the same object.
In this case, "hello" is treated as a constant which is assigned to a and b. So here == actually returns true. If you do this:
String a = new String("hello");
String b = new String("hello");
System.out.println(a == b);
You will get false.

Expressions vs Literals && Expressions vs Statements [duplicate]

This question already has answers here:
Expression Versus Statement
(21 answers)
Closed 7 years ago.
What's the significant difference between Expressions vs Literals && Expressions vs Statements in Java? I'm aware that an expression represents a simple value or a set of operations that produces a value. However, literals can also be a simple value which makes it a little confusing to make difference between them. Could smb explain the differences? Thanks in advance!
A literal is a notation for representing a fixed value in source code. For example: 'a', "a", Object.class, and 1 are all literals. Their value is known at compile-time, and they are expressions, since they evaluate to a single value.
Statements are complete units of execution. Most statements terminate with a semicolon. For example: new Object(); is a statement, while new Object() is an expression that returns a reference to a newly created object. Examples of statements that don't terminate with a semicolon are blocks and control flow statements.

Categories