Java String Memory-Address [duplicate] - java

This question already has an answer here:
How is String concatenation working in following
(1 answer)
Closed 1 year ago.
Why is the result false?
String s1 = "hello";
String s2 = "world";
String s3 = "helloworld";
String s4 = s1+s2;
System.out.println(s3==s4);
As I know, there's already one "helloworld" in the constant pool.
Thanks for answering, but what I want to ask is not the difference between "==" and "equals", I just want to make sure s1+s2; makes a new String, even though there's already one String Object with value "helloworld" in memory.

You need to understand that they all are object instance of class String
String s1 = "hello";
String s2 = "world";
String s3 = "helloworld";
This creates 3 objects with different values and different memory
String s4 = s1+s2;
Now you are again creating a new object with same value as s1 and s2 but since its a new object it has different memory.
System.out.println(s3==s4);
Now with this line you are trying to compare the values for these 2 objects and in String class the correct way to do it is by using equals() method i.e.,
System.out.println(s3.equals(s4));
For detailed information please check this:
https://www.geeksforgeeks.org/difference-equals-method-java/

(s3==s4) - means comparing references, not values. reference s3 is not the same as reference s4. s3 and s4 are two different instances of String.
use equals for comparing values of objects. override equals for your own classes if it necessary.

Related

String literals vs string objects hashcode [duplicate]

This question already has answers here:
why '==' is returning false even after my hashcode value is same
(3 answers)
Closed 5 years ago.
I read that strings declared as literals are created on String Constant Pool
String s1 = "Hello";
String s2 = "Hello"; -> This will not create a new object and will refer to the s1 reference.
And strings declared with new keyword are created on both Heap Memory and String Constant Pool
String s3 = new String("Hello"); -> This will create a new object in the heap.
But will it create a new constant in the String Constant Pool also or will it use the one from s1?
I have this following code.
Hashcode for all s1, s2, and s3 are return as same.
public class question1 {
public static void main(String[] args) {
String s1 = "Hello";
String s2 = "Hello";
String s3 = new String("Hello");
System.out.println(s1 == s2);
System.out.println(s1 == s3); // not sure why false result, s3 will create a separate constant in the pool? There is already a constant with value "Hello" created by s1. Please confirm if s3 will again create a constant.
}
}
I understant that == compares the object.
Are there two "Hello" defined in the String Constant Pool, one from s1 and one from s3?
String literals are automatically "interned," which places them in a pool. This minimizes the number of instances required. So, the two literals use the same String instance. hashCode() operates on the contents of the String in a consistent way. If two String instances have the same characters, then they will have the same hash code.

Java Strings Confusion [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 6 years ago.
String s1 = "abc";
String s2 = "abc";
String s3 = new String("abc");
String s4 = new String("abc");
if (s1 == s2) is giving true
while (s3 == s4) is giving false.
Can somebody give a detailed explanation onto what is String pool, heap, how many objects are created in each line and how many objects created in total.
Why s3==s4 is giving false?
A detailed explanation will be much appreciated.
When you do new String(...), it is evaluated at runtime and hence creates two different instances and you end up getting s3 == s4 as false. Same thing happens when you use StringBuilder and do something like sb.toString() which is again evaluated at runtime.
For Example,
StringBuilder sb = new StringBuilder();
String foo = sb.append("abc").toString();
String bar = new String("abc");
String foobar = "abc";
Here foo, bar and foobar are all different objects and hence foo == bar or foo == foobar will evaluate to false.
On the other hand s1 == s2 returns true because abc one declared, already exists in the String Pool and in this case both the objects points to the same reference in the pool.
String Class in java is defined in java.lang package and it is exactly that, a class and not a primitive like int or boolean.
Strings are developed to offer operations with many characters ans are commmonly used in almost all the Java applications
Some interesting facts about Java and Strings:
String in immutable and final in Java and in this case JVM uses String Pool to store all the String objects.
What are different ways to create String Object?
We can create String object using new operator like any normal java class or we can use double quotes (literal assignment) to create a String object.
There are too several constructors available in String class to get String from char array, byte array, StringBuffer and StringBuilderetc etc.
To your Question:
When we create a String using double quotes, JVM looks in the String pool to find if any other String is stored with same value. If found, it just returns the reference to that String object else it creates a new String object with given value and stores it in the String pool.
When we use new operator, JVM creates the String object but don’t store it into the String Pool. We can use intern() method to store the String object into String pool or return the reference if there is already a String with equal value present in the pool.
So when you do
String s1 = "abc";
String s2 = "abc";
those are checked in the StringPool and since s1 already exist there, s2 will take the same reference, hence, s1 ==s2 is true.
but when you do:
String s3 = new String("abc");
String s4 = new String("abc");
you are using the new operator, therefore the JVM is not checking if there is an string already in the heap, it will just allocate a new space for s4, so is s3==s4 ??? of course no.
Please take a look at the image below for a more illustrative example.

Count Distinct String Object Instances

How many distinct String object instances are created in the following code segment?
String s1 = new String("hello");
String s2 = "GoodBye";
String s3 = s1;
Not sure about all my reasoning here.
By using the keyword new that creates an instance from the String class, I am guessing that has to be an object. However, I am confused, is String after the new now considered a method because it has ( ) and then it is calling a String literal "hello" in it?
String s2 = "Goodbye";
I think this is a String literal, and since Strings are actually objects even the String literal is considered object. Not 100% sure if that is true.
String s3 = s1; Just refers back to s1. Therefore, it is not distinct.
So my answer is 2 distinct objects.
Please explain if I am a right or wrong.
The correct answer is 3.
String s1 = new String("hello");
String s2 = "GoodBye";
String s3 = s1;
The compiler will put both literals "hello" and "GoodBye" into a "constant pool" during compilation time, which then will be loaded by the classloader. So the JVM automatically interns all String literals used by this class, when it loads that class. More about this: When are Java Strings interned?. The String constant pool is then managed during runtime.
During runtime the JVM will create the third String object when it reaches the line String s1 = new String("hello").
So you would and up with three distinct String objects, where two of them contain the same word "hello". So s1.equals("hello") would be true, but s1 == "hello" would be false, because s1 references to a different String on the heap, than the literal "hello".
The line String s3 = s1 just creates a variable s3 with a copied reference to the String object of s1. It doesn't create a new object.
Also mind that you can "manually" add Strings into the String constant pool by using the method String#intern. So s1.intern() == "hello" is true, because the String reference returned from s1.intern() is the reference to the literal "hello" which was already in the constant pool.
If you like to get another and maybe more detailed explanation with some drawings about objects and their location, you can check this article on javaranch.

String pool Objects [duplicate]

This question already has answers here:
Questions about Java's String pool [duplicate]
(7 answers)
Closed 7 years ago.
Can you please clarify me, how many objects will be created in below case and why? I am slightly confused with this.
String s1 = "cat";
String s2 = "cat";
String s3 = "c"+"at";
String s4 = new String("cat");
String s5 = "kitty"+"cat";
String s6 = new String("kittycat");
String s7 = s5;
String s8= new String(s5); // Newly Added in this Question
Let's look step-by-step:
String s1 = "cat";
String s2 = "cat";
These two will be just the same constant pool entry created in your class file by javac compiler. When this class is loaded, this string (along with all other constant pool strings) will be automatically interned, thus it will be also merged with other "cat" strings in other classes.
String s3 = "c"+"at";
This is practically the same: if string concatenation can be computed during the compilation, it's done by javac. So it's practically the same as s1 and s2. This is covered by JLS, chapter 15.18.1:
The String object is newly created (§12.5) unless the expression is a constant expression (§15.28).
String s4 = new String("cat");
Here you explicitly create a new object. Java language guarantees that when you use a new keyword, you will have a new distinct object which cannot be the same as any of objects created previously. However if you use this object only in current methods (or in methods which can be inlined into the current) and don't use == operation to compare it with other strings, JIT compiler can skip the object allocation for optimization. But if you actually use == or System.identityHashCode, or this method is executed as interpreted frame, then it will be actually new object.
The "cat" string which is passed to the parameter is actually the same object as s1, s2, and s3.
String s5 = "kitty"+"cat";
This is similar to s3: the javac compiler will just create a "kittycat" string during the compilation. Looking into bytecode you cannot even know that there was a concatenation in the source.
String s6 = new String("kittycat");
This is similar to s4: new object is created explicitly. If you try to use s6 == "kittycat" later, you will get false.
String s7 = s5;
Here you just assign a reference to the previously created s5 string, thus no new object is created here.
So the answer is: at most 4 strings will be created, but in some cases it can be optimized down to 2 strings. And the most important: if you try to check how many strings you have from inside the same program (i.e. not using Java agent or analysing memory dump), you will always get four.
user3360241 - Your answer seems to be correct... Not sure why it's been down voted without giving any explanation... if you do this the size will be two..
Set<Integer> set = new HashSet<Integer>();
set.add(s1.hashCode());
set.add(s2.hashCode());
set.add(s3.hashCode());
set.add(s4.hashCode());
set.add(s5.hashCode());
set.add(s6.hashCode());
set.add(s7.hashCode());
System.out.println("size :: "+set.size());

Java String Objects [duplicate]

This question already has answers here:
How do I compare strings in Java?
(23 answers)
Closed 9 years ago.
I have the following code:
public class Porow{
public static void main (String[] args){
String s1 = "foo";
String s2 = "foo";
System.out.println(s1 == s2);
System.out.println(s1.equals(s2));
String s3 = new String ("foo");
System.out.println(s1 == s3);
System.out.println(s1.equals(s3));
}
}
which outputs:
true
true
false
true
I am trying to understand and explain what's going on here. And I need some guidance. Will I be right to say s1 and s2 are same objects stored in different parts of memory and that's why we get the first 2 trues?
Why is the 3rd output false? is s3 a different object? and why does it produce true with the equals method on s1? I'd appreciate some help. Thanks :).
EDIT:
This question is not about == nor equals() I know what they are. My question is more related to memory references and addresses. So don't just presume I'm asking about String Comparison. I'm asking about a whole different thing here.
That's because in the 3rd scenario, a new object is created(the new keyword creates a new string object) and == is used for object reference equality. That's why it returns false.
Whereas the equals() method is used for String value equality, and hence, it returns true.
In the first and second case, the "foo" String literal is interned and thus, both s1 and s2 refer the same String literal.
The == operator checks reference equivalence. If the two references are equivalent, then they're the same instance.
Your first example works because the strings are interned - but don't rely on this. equals() actually checks to see if the two Strings contain the same data.
With the new keyword, a new reference is created for the other string - hence, they no longer point to the same instance.
Because == tests that the strings refer to the same object and equals tests if they are equivalent. Your line
String s3 = new String ("foo");
constructs a new reference to the constant "foo" String. Take a look at What is String interning? for a bit more, but be aware that interning will use PermGen space.
String are put into a String pool
When you have
String s1 = "foo";
String s2 = "foo";
Only one "foo" is placed into the String pool.
So
s1 == s2 is true becuase they reference the Same String "foo" in the pool
To answer your question, your assumptions are right!
The last true s1.equals(s3) compares the value "foo", that's why they are equal.
So just remember with Strings
== compares Object reference
equals compares value.

Categories