0

Possible Duplicates:
Java String.equals versus ==
whats the difference between ".equals and =="

public String getName() {
    return new String("foobar");
}

if(getName() != "foobar2") {
    //Never gets executed, it should, wtf!.
}

if(!getName().equals("foobar2")) {
   //This works how it should.
}

So yeah my question is simple.. why doesn't != behave the same as !equals() aka (not Equals).

I don't see any logicial reason why one should fail, both are the same exact code in my mind, WTH.

Looking at java operators http://download.oracle.com/javase/tutorial/java/nutsandbolts/operators.html

You can clearly see equality == !=

are the equality operators, sure I usually use != only on numbers.. but my mind started wandering and why doesn't it work for String?

EDIT: Here's something that looks more like the actual issue..

    for (ClassGen cg : client.getClasses().values()) {
        final ConstantPoolGen cp = cg.getConstantPool();
        if(cp.lookupInteger(0x11223344) != -1) {
            for (Method m : cg.getMethods()) {  
                System.out.println("lots of class spam");
                if(m.getName() != "<init>") continue;
                System.out.println("NEVER GETS HERE, 100% SURE IT HAS CONSTRUCTOR LOL");
            }
        }
    }
Community
  • 1
  • 1
SSpoke
  • 5,656
  • 10
  • 72
  • 124
  • I am unable to reproduce this behavior: http://ideone.com/0GhxJ – Daniel Pryden Aug 16 '11 at 00:03
  • Also, `!=` is not **at all** the same code as `!equals()`. The `!=` **operator** compares for **reference** inequality, while `equals()` is a **method**. – Daniel Pryden Aug 16 '11 at 00:05
  • You may also be interested in this question: [Java String.equals versus ==](http://stackoverflow.com/questions/767372/java-string-equals-versus) – Daniel Pryden Aug 16 '11 at 00:07

4 Answers4

2

Using != means that you check for the instance reference in the memory, and the same instance will give you true on that comparison.

When you do a new String("foobar"), a new "foobar" is created in the memory, and the comparison using == returns false.

Calling a intern() on that new string may change this behavior, since the String will now be grabbed or added to the String pool.

In any case, it's safer to use the 'equals()'.

sgibly
  • 3,828
  • 1
  • 21
  • 21
  • Also - you can read this little article that demonstrate it - http://javatechniques.com/blog/string-equality-and-interning/ – sgibly Aug 16 '11 at 00:10
  • The `==` and `!=` operators don't necessarily test bit-wise equivalence of references. What they test is whether two references identify the same object instance. Some kinds of GC could benefit from knowing whether a reference has been modified since the last major GC cycle [a reference which hasn't been modified since then need not be examined during an Eden collection cycle], and could legitimately use a bit in the reference for that purpose if the bit was ignored when using the reference or comparing it to another. – supercat Dec 22 '14 at 17:57
1
public static void main(String[] args) throws Exception {

    if (getName() != "foobar2") {
        System.out.println("1");
    }

    if (!getName().equals("foobar2")) {
        System.out.println("2");
    }
}

public static String getName() {
    return new String("foobar");
}

For me this outputs:

1
2

But those two checks are not equivalent. The first check is checking whether the object returned by getName() is the same object that was created for the string literal "foobar2", which it's not. The second check is probably the one you want, and it checks that the VALUE of the String object returned by the getName() method is equal to the VALUE of the String object created for your "foobar2" string literal.

So both checks will return true, the first one because they aren't the same object and the second one because the values aren't the same.

Jason Wheeler
  • 872
  • 1
  • 9
  • 23
  • Yeah, I got the same result at [ideone](http://ideone.com/0GhxJ). I have no idea how SSpoke could have got the result described above. – Daniel Pryden Aug 16 '11 at 00:14
  • Well it was just a example I did.. it actually doesn't work in my program which has a flow a bit changed I guess.. it's inside of a loop actually.. – SSpoke Aug 16 '11 at 00:16
  • Updated with more like looking actual code. – SSpoke Aug 16 '11 at 00:24
0

Operators only apply to primitives, not Objects, so a String comparison must be done equals, as that operates at the Object level.

--EDIT--

My comment was meant more along the lines of "the value of an Object cannot be compared in the expected way as in other languages". Of course you can use == signs, but not for a textual comparison. This is the classic question that is asked every time someone migrates to Java from a scripting language, or another language that does support operators for text comparison on Strings.

atrain
  • 9,139
  • 1
  • 36
  • 40
  • Haha a primitive is also a object no? look at Integer.class Float.class etc.. they are primitives but they are also Objects! – SSpoke Aug 16 '11 at 00:01
  • 1
    @SSpoke primitives are not objects, now. `int i = 0;` makes i a primitive of type int `Integer i = new Integer(0);` makes i and object of type Integer. Integer is an object wrapper for ints so that they can be used in places where only Objects are allowed. int is a primitive type though. They are different things. – Paul Aug 16 '11 at 00:02
  • @SSpoke Like PaulPRO said, Java primitives are not objects. That said, the lines get blurred with Java's [autoboxing/unboxing](http://download.oracle.com/javase/1.5.0/docs/guide/language/autoboxing.html) – Zach L Aug 16 '11 at 00:05
  • Where are only Objects allowed though? i never encountered such a spot?. They seem to all work together just fine.. if you needed to do some advanced integer stuff why not just make Integer a factory class? I just don't get that. Ahh.. stupid question.. i guess you mean `void(Object a)` which can be casted to anything.. but how u cast it to number got it! – SSpoke Aug 16 '11 at 00:06
  • 1
    `Operators only apply to primitives, not Objects[snip]` That's incorrect. The `==` operator works perfectly fine with objects. Case in point: `someObj == null` and `someObj == someOtherObj` – Jeremy Aug 16 '11 at 00:07
  • Jeremy how about `hashCode` implemention does that work for `==` of objects? – SSpoke Aug 16 '11 at 00:08
  • @SSpoke: The `hashCode()` method is something entirely different. It's not meant to decide object equality. – Jeremy Aug 16 '11 at 00:10
0

A string is an Object, not a primitive. == and != compare two primitives to each other. To compare strings you need to loop trough each character and compare them in order which is what .equals() does.

If you do any OOP in Java you need to override equals when you want to do equality checks on the Objects, and implement Comparable and .compare() if you want to be able to do things like sort them.

Here is a quick example of equals:

public class Person {
    public name;

    public Person(String name) {
        this.name = name;
    }

    public boolean equals(Object o){
        if(o instanceof Person)
            if(this.name.equals(o.name))
                return true;
        return false;
    }
}

Now a Person can be compared to another Person like:

person1.equals(person2)

Which will only return true if both people have the same name. You can define what makes two objects equal however you want, but objects are only == if they are really just two pointers to the same object in memory.

Paul
  • 139,544
  • 27
  • 275
  • 264
  • Blah I still find it strange when I program in C#.. well it's .NET after all I got used to using `!=` and `==` on strings.. blah i guess thats where the differences kick in.. – SSpoke Aug 16 '11 at 00:03
  • `!=` and `==` still work the exact same way in Java as in almost any other language. The difference is you have a wrapper class for a primitive which is the same but with a capital letter and it has helper methods like "equals()" which checks to see if the value is the same. This is very helpful for many reasons. – citizen conn Aug 16 '11 at 00:07
  • 1
    C# supports Operator overloading: http://msdn.microsoft.com/en-us/library/8edha89s(v=VS.71).aspx So `==` can be defined to mean anything. That's why it works on strings, but it could also be overloaded to do the same thing as `!=` if someone wanted to. Java doesn't allow operator overloading although they went have way with strings and defined `+` to do concatenation. – Paul Aug 16 '11 at 00:14
  • So the `boolean equals(Object o)` uses name `==` name which does a reference equality okay.. and `instanceof` checks if both classes are the same signature. But it `never` does equality check if name is the same string as in ASCII values LOL!, Unless `person1.equals(person2)` does the String.equals().. under the hood then does the overloaded equals after? – SSpoke Aug 16 '11 at 00:27
  • @SSpoke Sorry haha, I meant `this.name.equals(o.name)` – Paul Aug 16 '11 at 00:29
  • haha so everybody makes this mistake or i messed you up HAHA!.. anyways good knowledge here. I don't know whose answer to accept you helped me the most.. yet other people got voted more then you.. I'm not registered cannot vote or anything blah i'll accept yours – SSpoke Aug 16 '11 at 00:33