0

I want to understand the == operator in JAVA;

String name = "Object Oriented";
String str1 = "Object";
String str2 = "Object";
String str3 = new String("Object");
String str4 = name.substring(0,6);
String str5 = name.substring(0,6);
String str6 = "Obj" + "ect";

System.out.println(str1 + "==" + str2 + ": " + (str1 == str2));
System.out.println(str1 + "==" + "Object" + ": " + (str1 == "Object"));
System.out.println(str1 + "==" + str6 + ": " + (str1 == str6));
System.out.println(str1 + "==" + str3 + ": " + (str1 == str3));
System.out.println(str1 + "==" + str4 + ": " + (str1 == str4));
System.out.println(str4 + "==" + str5 + ": " + (str4 == str5));

The output is weird;

Object==Object: true
Object==Object: true
Object==Object: true
Object==Object: false
Object==Object: false
Object==Object: false

In the Deitel How to Program Java book, it says;

To conserve memory, Java treats all string literals with the same contents as a single String object that has many references to it.

So, str1 and str2 are individual string literals, and Java treats them as a single object. Similarly, str6 is the same content.

The "str3" is a new object, it is the supposed output (false).

But, I don't understand the last two. What is the difference between "str4" and "str6", "str2" and "str5"?

Is the "str1" a variable and the other ones are objects?

I know "equal()" method. I know the difference between two methods.

this is not the same question with this

babeyh
  • 659
  • 2
  • 7
  • 19
  • 1
    All of the `String`(s) are objects. String is an Object type. Never compare Object types with `==`. Because it compares **references**. `String a = "a"; String b = new String(a);` a will never `==` b. They are distinct **references**. `String c = a.substring(0, 1);` is also a *distinct* **reference**. – Elliott Frisch Jun 13 '23 at 12:24
  • 1
    *"What is the difference of "str4" (or str5)?"* - They're different for the exact same reason `str3` is different, so I guess it's not clear to me why one behavior is expected but the other is not. In the code shown, every instance of the literal string `"Object"` is optimized by the compiler into a single `String` object with multiple references to it. (The same is true of literals like `"=="` and `": "`, though the code doesn't observe those.) But instances created at runtime aren't optimized by the compiler because they're not literal values and don't exist until runtime. – David Jun 13 '23 at 12:35
  • 1
    See also: [_"What is Java String Pool?"_](https://www.digitalocean.com/community/tutorials/what-is-java-string-pool) – Mr. Polywhirl Jun 13 '23 at 12:46
  • 1
    @David - 1) it is not an "optimization". The behavior of multiple "equal" string literals referring to the same `String` objects is actually mandated by the JLS. 2) Under some circumstances, `String` instances created at runtime *do* ultimately refer to the same object.. Examples include when `intern` is used and when GC string deduping is enabled. – Stephen C Jun 13 '23 at 12:48
  • @StephenC: "Optimization" may have indeed been the wrong word, that's fair. My Java terminology is rudimentary at best. My understanding is simply that the compiler sees these literals, sees they're the same, and knows that strings are immutable so it only needs one reference to one in-memory string instance. Which would satisfy the `==` comparison in the code shown. I *suspect* the OP really just needs to properly compare strings without getting deep into the internals, making the whole thing a moot point anyway. – David Jun 13 '23 at 13:00
  • Indeed. The best advice is to never use `==` to compare strings. Plain and simple. Hence the duplink. – Stephen C Jun 13 '23 at 23:51

1 Answers1

-1

The == operator in Java does not compare whether objects are equal, but rather checks if the objects have the same memory address.

Strings in Java are immutable. When you create a string using the assignment operator "=", such as String str = "Object", Java references the same memory address for optimization purposes. That's why you get a true result when comparing such strings using the == operator. However, if you create a new string using new String() or a substring, Java creates a new object with a different memory address, which is why the comparison returns false.

Note: To compare the content of the objects, use the str1.equals(str2) method.

class Scratch {
  public static void main(String[] args) {
    String name = "Object Oriented";
    String str1 = "Object";
    String str2 = "Object";
    String str3 = new String("Object");
    String str4 = name.substring(0,6);
    String str5 = name.substring(0,6);

    System.out.println(str1 + "==" + str2 + " | "
        + System.identityHashCode(str1) +"==" + System.identityHashCode(str2)
        +": " + (str1 == str2));
    System.out.println(str1 + "==" + "Object"  + " | "
        + System.identityHashCode(str1) +"==" + System.identityHashCode("Object")
        + ": " + (str1 == "Object"));
    System.out.println(str1 + "==" + str3  + " | "
        + System.identityHashCode(str1) +"==" + System.identityHashCode(str3)
        + ": " + (str1 == str3));
    System.out.println(str1 + "==" + str4  + " | "
        + System.identityHashCode(str1) +"==" + System.identityHashCode(str4)
        + ": " + (str1 == str4));
    System.out.println(str4 + "==" + str5  + " | "
        + System.identityHashCode(str4) +"==" + System.identityHashCode(str5)
        + ": " + (str4 == str5));
  }
}
Object==Object | 225991731==225991731: true
Object==Object | 225991731==225991731: true
Object==Object | 225991731==342597804: false
Object==Object | 225991731==1308244637: false
Object==Object | 1308244637==1860944798: false
Borislav Gizdov
  • 1,323
  • 12
  • 22