Hello everyone,
Today we’re diving into a Java topic that causes headaches for many developers, especially at the beginning: The
Comparing strings using the == operator. You’ve probably heard that strings are always with you
.equals() should compare. But then why do the following tests work if we use ==?
String a = "127";
String b = "127";
String c = "128";
String d = "128";
boolean comp = a == b;
boolean comp2 = a == c;
boolean comp3 = b == c;
boolean comp4 = c == d;
assertTrue(comp);
assertFalse(comp2);
assertFalse(comp3);
assertTrue(comp4);
If you try this in your code, you will notice that all assertTrue and assertFalse statements are successful. But how can that be? Let’s solve the mystery.
String literals and the string pool
The secret lies in the String Pool (also known as String Intern Pool or String Constant Pool). This one Pool is a special area in Java’s heap memory where string literals are stored.
If the Java Virtual Machine (JVM) encounters a string literal (i.e. a string that is converted directly into the code in duplicate
If the quotation marks are present, such as "127" or "Hello"), the following happens:
- Checking in the string pool: The JVM first checks whether a string with the same value is already in the string pool exists.
- Does he exist?
- Yes: If the string already exists, simply place a reference to this already existing string in Pool returned. No new string is created.
- No: If the string is not already in the pool, a new string is created in the pool and a reference returned to it.
The magic behind the tests
Let’s look at your examples in detail:
String a = "127";
String b = "127";
Here both string literals are set to the value "127". Since "127" is a string literal, the JVM will first
check whether "127" is already in the string pool. Since this is the first time for this value, "127" is created in the pool,
and both a and b get a reference to the same String object in the String Pool. Therefore a == b *
*true**.
String c = "128";
String d = "128";
Exactly the same thing happens here as with "127". "128" is also a string literal. It is created in the string pool (
if not already present), and c and d point to the same object in the pool. Therefore c == d is also
true.
The catch: Why .equals() should be standard
Now comes the interesting part, which often causes the confusion to arise:
boolean comp2 = a == c; // a="127", c="128"
boolean comp3 = b == c; // b="127", c="128"
In these cases we compare references to different string literals. "127" and "128" are natural
two different values. The JVM creates them as separate objects in the string pool. a and b refer to the object
for "127", while c and d point to the object for "128". Since a (or b) and c refer to different ones
Memory addresses show, the == comparison (which compares the references) is correct here false.
When == doesn’t work
The == operator only works reliably for string comparisons if both strings are used as literals in
Code are defined and the JVM applies string interning. As soon as a string is created in another way, e.g.
through:
new String("Value"): Here a new object is explicitly created in the heap, even if “Value” is already in the string Pool is. The reference is then different.- String operations:
String result = str1 + str2;orString result = str.substring(0, 3);also produce * new String objects* in the heap.
In these cases, comparisons with == would almost always return false, even if the string contents are identical
would be.
String s1 = "Hello";
String s2 = "Hello";
String s3 = new String("Hello");
System.out.println(s1 == s2); // true (both literals, same object in the pool)
System.out.println(s1 == s3); // false (s3 is a new object in the heap)
System.out.println(s1.equals(s3)); // true (contents are the same)
Conclusion
The examples show that == can work for string literals because the JVM uses a string pool
optimization is carried out. But never rely on it!
Best practice: ALWAYS use the .equals() method to compare string contents. She compares
the actual character sequences of the strings and is therefore the safe and correct method for
String content comparison in Java, regardless of how the strings were created.
Do you have any questions about this or have you ever stumbled upon this behavior? Let me know!
![[EN] Strings in Java: Warum `==` manchmal funktioniert und manchmal nicht](/images/BlogHeaderStringPool.jpeg)