String "==" in java to check the link, why does this code return true?

Possible duplicate:
If == compares links in Java, why does it evaluate true with these lines?
Comparing strings with a logical operator in Java

public static void main(String[] args) { String a = "ab"; final String bb = "b"; String b = "a" + bb; System.out.println(a == b); } 

why does it print true?

but

 public static void main(String[] args) { String a = "ab"; String bb = "b"; String b = "a" + bb; System.out.println(a==b); } 

it prints false.

+6
source share
4 answers

You see the result of two actions working in combination:

  • The compiler processes "a" + bb at compile time, and not at runtime, because bb is final , and therefore it knows that it can do this. (There are other times when he knows this.)

  • All lines generated by the compiler are interned. For more on interning, see this answer in another StackOverflow question about == in Java.

So, the result: a and b point to the same instance of the string, and therefore == returns true .

+6
source

The compiler evaluates the string at compile time as final and will never change.

 final String bb = "b"; String b = "a" + bb; 

"a" + bb evaluated at compile time

+6
source

Java will set constant constants (trailing strings) and literals (create one instance of each row in the internal pool), and this way you can get the same instance even if it is "created" by concatenation.

As others have already pointed out, compiler optimization will actually turn concatenation into a single literal ("ab").

You can never fully rely on the semantics of == String, so equals(..) should always be used.

Edit: To clarify the above sentence:

With objects, == always means that links are compared, and it will always return true if both links are the same. However, you cannot always rely on getting the same object reference (for example, in your example, when a simple final changes the behavior or in frameworks such as Hibernate, etc.) - that’s why you should usually use equals(...) .

Of course, you can use == if you need physical equality (the same object) instead of logical equality (the same value).

Another example where == will have different results, although both in terms of location should both be true:

 Integer l1 = 0; Integer l2 = 0; l1 == l2; //most often true, since Integer objects up to 127 are cached Integer l1 = 1000; Integer l2 = 1000; l1 == l2; //most often false, since those are not cached anymore 

Please note that with “more often” I mean that this can change between versions of Java (if not different JVMs), although this is not very likely.

+5
source

JLS indicates this in the String Literals section:

Each string literal is a reference (§4.3) to an instance (§4.3.1, § 12.5) of the String class (§ 4.3.3). String objects have a constant value. String literals or, more generally, strings that are constant expression values ​​(§15.28) are “interned” to share unique instances using the String.intern method.

Thus, a test program consisting of a compilation unit (§7.3):

 package testPackage; class Test { public static void main(String[] args) { String hello = "Hello", lo = "lo"; System.out.print((hello == "Hello") + " "); System.out.print((Other.hello == hello) + " "); System.out.print((other.Other.hello == hello) + " "); System.out.print((hello == ("Hel"+"lo")) + " "); System.out.print((hello == ("Hel"+lo)) + " "); System.out.println(hello == ("Hel"+lo).intern()); } } class Other { static String hello = "Hello"; } 

and compilation unit:

 package other; public class Other { static String hello = "Hello"; } 

outputs the result:

 true true true true false true 

BTW: OMM (jdk1.6.0_21, Ubuntu), the above code does not compile until I do other.Other.hello public , and then it outputs:

 true true true true true true 

Update: no, my fault. My IDE automatically added final to the local variable declaration. If I remove this, I get:

 true true true true false true 
+4
source

Source: https://habr.com/ru/post/898061/


All Articles