Why do != and == not behave like the equals method in Java? [duplicate]
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 quest开发者_开发百科ion 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");
}
}
}
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()'.
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.
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.
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.
精彩评论