Difference between == and .equals in Java.

前端 未结 7 1268
太阳男子
太阳男子 2021-01-14 12:11

I know this has been covered but I\'ve seen inconsistent arguments here on SO.

So if I have:

String a = \"apple2e\";
String b = \"apple2e\";

System.         


        
相关标签:
7条回答
  • 2021-01-14 12:26

    a and b are two different references to the same object -- PROBABLY

    "a==b? " + a
    

    evaluates to the string "a==b? apple2e" which is definitely not the same (either == or equals) as the string "apple2e"

    So your code:

    System.out.println("a==b? " + a == b);
    

    is just testing if "a==b? apple2e" is the same as "apple2e" which it is not (no matter how you define same).

    0 讨论(0)
  • 2021-01-14 12:27

    Your first example is actually true. The expression in the println just isn't doing what you meant.

    String a = "apple2e";
    String b = "apple2e";
    
    System.out.println("a==b? " + (a == b));
    

    Will print a==b? true note the all important grouping!

    You are correct that a and b are two different references to the same object. This is exactly why == returns true when you test it! == tests if two different pointers point to the same location in memory. Both a and b are references to the same place in memory that holds the interned compile time "apple2e" string.

    Now if you did this

    String a = new String("apple2e");
    String b = new String("apple2e");
    
    System.out.println("a==b? " + (a == b));
    

    It actually will print a==b? false. Because you made two different objects in memory, a and b point to different places.

    0 讨论(0)
  • 2021-01-14 12:40

    a == b looks to see if the two objects point to the same object in memory. Because they don't, even though their internals are the same, a == b will be false. 1 == 1 will be true though, because integers are primitive variables, while Strings are actually objects.

    a.equals(b) is an instance method that internally checks to see if the two strings have the same characters.

    If you did:

    String a = "hello";
    String b = a;
    

    Then a == b would be true.

    0 讨论(0)
  • 2021-01-14 12:44

    As I understand it, it's because a and b are two different references to the same object (apple2e).

    Because of string interning, and only because of string interning a and b are different references to the same String object.


    Unfortunately, your code does not do what you think it does. Try this:

    String a = "apple2e";
    String b = "apple2e";
    
    System.out.println("a==b? " + a == b);    // "false"
    System.out.println("a==b? " + (a == b));  // "a==b? true"
    

    Java automatically interns all string literals. That is why the second sysout prints what it does. The first sysout prints only "false" because string concatenation (+) has higher precedence than ==, so it's equivalent to this:

    System.out.println("a==b? apple2e" == "apple2e");
    

    I don't think that's what you meant to test!

    This, on the other hand, will give you two separate String instances:

    String a = new String("apple2e");
    String b = new String("apple2e");
    
    System.out.println("a==b? " + (a == b));  // "a==b? false"
    

    Which would schematically look like

    a (reference_id 123) ---------------  "apple2e"
    
    b (reference_id 456) ---------------  "apple2e"
    

    and can be reduced to the original situation using String#intern():

    String a = new String("apple2e").intern();
    String b = new String("apple2e").intern();
    
    System.out.println("a==b? " + (a == b));  // "a==b? true"
    

    e.g.

    a (reference_id 123) ------+
                               +---------  "apple2e"
    b (reference_id 456) ------+
    
    0 讨论(0)
  • 2021-01-14 12:44

    If you change to the following: System.out.println("a==b? " + (a == b));

    You get a==b? true

    Whats happening here is that a and b both point to an internal cache of Strings that is maintained by the String class.

    Here is the implementation of String.equals()

    public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = count;
        if (n == anotherString.count) {
        char v1[] = value;
        char v2[] = anotherString.value;
        int i = offset;
        int j = anotherString.offset;
        while (n-- != 0) {
            if (v1[i++] != v2[j++])
            return false;
        }
        return true;
        }
    }
    return false;
    }
    

    anObject must be a String in order to return true, if it is a reference to the same Object, then it returns true immediately. Otherwise as you can see, is is doing a character by character comparison.

    0 讨论(0)
  • 2021-01-14 12:48

    apple2e is not an object. It is the value pointed by the reference.

    String a = "apple2e";
    String b = "apple2e";
    

    Here, a, b are objects ( references ) to the value apple2e stored at two different locations.

    0 讨论(0)
提交回复
热议问题