Question about == operator in java

public class Demo { public static void main(String[] args) { String s1 = "Hello"; String s2 = "Hello"; System.out.println("s1 == s2 " + (s1 == s2)); String s5 = "Hel" + "lo"; String s6 = "He" + "llo"; System.out.println("s5 == s6 " + (s5 == s6)); String s7 = "He"; String s8 = "Hello"; s7 = s7.concat("llo"); System.out.println("s7 == s8 " + (s7 == s8)); String s10 = "He"; s10 = s10 + "llo"; System.out.println("s1 == s10 "+(s1 == s10)); } } 

In the previous code, s7 == s8 and s1 == s10 give false. Can someone please explain to me what really happened here in s7 = s7.concat ("llo"); and s10 = s10 + "llo"; I understand the == operator checks the link and equals () checks the contents of the object. But I need to know why the bit patterns of the reference variables s7 and s10 are different from s8 and s1. If these things are related to strings generated by compilation time and strings generated at runtime, then how can I determine if this is compilation time or a runtime string?

+4
source share
7 answers

The reason this happens is because Java is optimized in the compiler. When he sees that you assign the literal string "Hello" to s1, it uses the same "Hello" for s2, since all Java String operations are non-destructive (for example, they return a clone, and not modify the original), so this is a safe thing.

The same goes for "Hel" + "lo" vs "He" + "llo" ; it's smart enough to realize that they are one and the same.

Others are complex enough that they cannot optimize them, and therefore, you get separate objects.

+11
source

== does not check bit patterns, it will compare the memory address for objects. Only the same object has the same memory address.

+4
source

Clint’s answer is fine, but I will continue it further and explain it at the compiler level.

As you know, s1 and s2 will refer to the same instance of the string "Hello" .

For s5 and s6 compiler sees constant expressions. That is, he sees an operation between two constants (string literals). The compiler knows how to add lines and what the result will be. Since the values ​​are known immediately at compile time, this addition is for you, leaving the literal string "Hello" . Therefore, it has the same meaning as s1 and s2 , so everyone will refer to the same instance.

s7 cannot be simplified in the same way. s7 first starts with "He" course. The difference here is that s7 = s7.concat("llo"); as reassigning s7 to the result of a function call. It cannot be simplified as it is. As for the Java compiler, the results of all function calls are not known at compile time. Since he does not know the resulting value, it cannot be simplified and left as is. The resulting call returns a new instance of the string "Hello" , which is not the same instance as the compile-time instance (which s8 shares).

s10 also cannot be simplified. s10 first starts with "He" course. Then reassigned s10 = s10 + "llo"; This cannot be simplified. Why can you ask? Well s10 is not a finite variable expression. From a technical point of view, the compiler does not know this value, because it is not a constant. If s10 was declared as final String , then it can be folded (if assigned to another variable).

So, consider this version of the test code:

 public static void main(String[] args) { String s1 = "Hello"; String s2 = "Hello"; System.out.println("1: s1 == s2 " + (s1 == s2)); // 1 String s3 = "Hel" + "lo"; String s4 = "Hel".concat("lo"); System.out.println("2: s1 == s3 " + (s1 == s3)); // 2 System.out.println("3: s1 == s4 " + (s1 == s4)); // 3 String he = "He"; String s5 = he + "llo"; String s6 = he.concat("llo"); System.out.println("4: s1 == s5 " + (s1 == s5)); // 4 System.out.println("5: s1 == s6 " + (s1 == s6)); // 5 final String fhe = "He"; String s7 = fhe + "llo"; String s8 = fhe.concat("llo"); System.out.println("6: s1 == s7 " + (s1 == s7)); // 6 System.out.println("7: s1 == s8 " + (s1 == s8)); // 7 } 

Can you figure out which lines are correct?

true, true, false, false, false, true, false
You might be wondering why 3 and 7 are not true. Short answer, the Java compiler was not programmed
to be smart enough to recognize the concat () call, therefore it is treated like a regular function call.

+4
source

The equals statement checks if the links are the same (i.e. pointing to the same object), and not that the values ​​of the links are the same. If you need to check if one line is equal to another, you should use the built-in .equals method. This will make a comparison of the values ​​of the objects. eg.

 final String expectedValue = "Foo"; final String actualValue = "F" + "oo"; if (expectedValue.equals(actualValue)) { // This will trigger where == would not } 

Also, for security, if you are comparing two strings and one is a constant, it is usually best to call equal in constant, i.e.

 String myValue = getMyValue; boolean theSame = "Some value".equals(myValue); 

Instead

 String myValue = getMyValue; boolean theSame = myValue.equals("Some Value"); 

The reason is that the second form is prone to throwing a null pointer, which can be avoided by calling equals () on a constant string, which is guaranteed to be there.

0
source

You cannot make any assumptions about string objects.

The VM could work hard to make sure that two string objects containing exactly the same char array exist at the same time, while other virtual machines allow duplication.

0
source

The == operator only checks if two objects have the same address (pointer). Only for primitive types that are not referenced (e.g. int, char, etc.), It compares the value.

You need to use something like s1.equals(s2) to compare the contents of two strings.

0
source

In the example you pointed out, this is what happens:

 String s7 = "He"; //s7 is an object referencing a part of memory holding "He" String s8 = "Hello"; //s8 is an object referencing a part of memory holding "Hello" s7 = s7.concat("llo"); //s7.concat("llo") created a new object in memory that contains "Hello" and s7 now references this now object (s7==s8) //checks if the equality of the object reference and this is false since they reference different memory addresses. (s7.equals(s8)) //this will compare s7 and s8 however way the String class compares two String objects. 
0
source

All Articles