views:

662

answers:

5

So I have purchased the book "Java for Dummies" 4th Edition, and I must say it is probably the best 30 dollars I have ever spent on a book. I'm not new to coding, am actually fairly decent at at it if I say so myself.

However, I've come across a line of code that has me a touch confused:

public void setName(String n)
{
     if(!n.equals(""))
     {
          name = n;
     }
}

My question comes up on the third line, the if(!n.equals("")) part...I know how if loops work (ie: if(this == that){do stuff}), but I've not seen the !n.equals("") set up before. Can anyone please explain it to me?

PS: Just to throw in a guess. Is it the same as:

public void setName(String n)
{
     if(n != "")
     {
          name = n
     }
}

I think it's just a way to make sure that if the user doesn't type in a name (ie. myAccount.setName = ""; ) it doesn't kick back an error and runs like normal, but I wasn't sure.

Thanks in advance for the help!

EDIT: changed my "myAccount.name = "";" to "myAccount.setName = "";", sorry about the confusion.

THANK YOU: Goes to Asaph, appreciate the answer! Same to Lucas Aardvark, he answered as well, but Asaph answered my verification comment in his own answer first, thanks to everyone!

+5  A: 
if(!n.equals(""))
{
     name = n;
}

means if n is not an empty String, assign its value to name.

In Java, every Object has an equals(Object o) method to test for equality with another Object. The == operator is typically used to compare primitives. It can also be used to compare Objects for "sameness". ie. the two Objects are in fact the same instance. This comes in handy for immutable types such as Strings and all the Object wrappers for the primitive types such as Integer and Long.

Asaph
Isn't this bad form? Wouldn't it be better to use n.length() > 0 ?
Chris Kaminski
It's much clearer to compare it to the particular string you are interested (or not interested) in. `!n.isEmpty()` is probably better. Actually better would be to throw an `IllegalArgumentException` for the illegal value.
Tom Hawtin - tackline
@Tom: `n.isEmpty()` only works for Java 1.6 and later.
Stephen C
A: 

Consider this:

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

Both a and b are String OBJECTS, each with its own memory allocation and thus a unique address. a and b are at different addresses. When you code the boolean expression

a == b

you are comparing the addresses of the objects, not their contents. To compare the contents you must use the String object's equals() method.

An object has a physical location in memory, which is unique for each object -- no two distinct objects can have the same memory address -- and its contents or value. The == operator compares the addresses of the objects; when you code a==b you are asking if a and b are aliased names for the same object -- do a and b refer to the same physical location. a.equals(b) asks if the two objects, wherever they may be, have the same value.

This is complicated somewhat by compiler "interning", where the compiler may detect at compile time that two constants have the same value and reuse the same object, but this won't be true for values created at runtime.

Jim Garrison
ok...so what's the difference between comparing the objects and addresses? is a==b different from a.equals(b)? (though I may have just butchered that line, I don't quite understand it, which is why I posted here.
Jeff
Actually, they will be the same - compile time constant strings are interned.
Tom Hawtin - tackline
An object has a physical location in memory, which is unique for each object -- no two distinct objects can have the same memory address -- and its contents or value. The == operator compares the addresses of the objects; when you code a==b you are asking if a and b are aliased names for the same object -- do a and b refer to the same physical location. a.equals(b) asks if the two objects, wherever they may be, have the same value.
Jim Garrison
a and b in your code are not objects, they are variables. a points to exactly the same object then b, so a == b returns true in that code! The compiler assign the same (interned) String to both. Try it out!You would get a new String doing something like b=new String("")
Carlos Heuberger
+9  A: 

In java, strings are immutable but not interned, so if(""==n) might or might not be true for another string for which "".equals(n) is true.

Just to confuse you more, this is bad code, it will get a NullPointerException if called with null as the argument. It should be written as "".equals(n)

ddyer
Yes, the best thing here would be if( n != 0 || ! n.equals(""))
slim
@slim: Too much C for you me thinks :p (n != 0) is invalid in Java.
_ande_turner_
In this case, your suggestion creates worse code: `"".equals(n)` where `n == null` returns `false`, and therefore `(!"".equals(n))` evaluates to `true` which means he will assign `null` to `name`. A `NullPointerException` would actually be preferable to a consumed error. A `NullPointerException` is actually the desired response in this situation. Coding "defensively" and consuming `null` references means the caller who's code is broken never finds out about it. A user can't enter a `null`, which mean the code is broken, and therefore an `Exception` should be thrown.
_ande_turner_
MattC
MattC
A: 

the method equals() will return a boolean value which states that the Object being passed in is 'equal to' the Object making the call. This 'equals to' method can be overridden in classes to make their own test. In the case of String, the test is whether the value of the original String is the same as the value of the String representation of the Object being passed in.

As it returns a boolean, you can negate the value with a !, so the test is 'is the method argument not an empty String?' Yes? then assign it to our name variable.

== will always test whether the Object on the left is the same as the Object on the right, as it compares references.

akf
+2  A: 

The equals() method compares contents of the two strings. The == and != operators tell you whether the two String objects are the same object or not. Two different strings with the same contents, and hence equals() to each other, may still be != to each other. Even though Strings aren't mutable, it helps to understand the difference by imagining that Strings are mutable, and then equals() means "are currently the same" and == means "will always be the same".

The safe rule is to always use equals() unless you're sure both strings are interned. Quoting:

It follows that for any two strings s and t, s.intern() == t.intern() is true if and only if s.equals(t) is true.

All literal strings and string-valued constant expressions are interned.

Keith Randall