一行Java代码及其作用是什么?

7
我已经购买了《Java for Dummies》第四版的书籍,花费30美元购买这本书可能是我花在书上最好的投资。我并不是编程新手,如果我这么说是相当不错的。
然而,我遇到了一行代码让我有些困惑:
public void setName(String n)
{
     if(!n.equals(""))
     {
          name = n;
     }
}

我的问题出现在第三行,if(!n.equals(""))这部分...我知道if循环的工作原理(即:if(this == that){do stuff}),但我以前没有看到过!n.equals("")这种设置。 有人可以解释一下吗?

PS:只是猜测。 它是否与以下内容相同:

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

我认为这只是一种确保如果用户没有输入名称(即myAccount.setName =“”;)它不会返回错误并像平常一样运行的方法,但我不确定。
感谢您提前的帮助!
编辑:将我的“myAccount.name =“”;”更改为“myAccount.setName =“”;”,对混淆表示抱歉。
感谢Asaph的答案!同样感谢Lucas Aardvark的回答,但是Asaph先在自己的答案中回答了我的验证评论,感谢大家!

5
仅是建议,在Java中永远不要使用 == 或 != 来比较字符串。[ 对于基本数据类型可以使用 == 或 !=,但对于非基本数据类型则不应使用 ]。 - Rakesh Juyal
2
考虑使用Sun Java教程来补充您的新知识。http://java.sun.com/docs/books/tutorial/ - Thorbjørn Ravn Andersen
5个回答

9
在Java中,字符串是不可变的,但不是内部化的,因此如果对于另一个字符串而言"".equals(n)为真,则""==n可能有可能不为真。
仅仅为了让你更加困惑,这是糟糕的代码,如果使用null作为参数调用它将会得到一个NullPointerException。应该写成"".equals(n)。

是的,这里最好的方法是 if(n != 0 || !n.equals(""))。 - slim
1
@slim:我想你的C语言太多了:p 在Java中(n != 0)是无效的。 - Ande Turner
2
在这种情况下,你的建议会导致更糟糕的代码:"".equals(n) ,其中 n == null 返回 false,因此 (!"".equals(n)) 的结果为 true,这意味着它将把 null 赋值给 name。与消耗错误相比,NullPointerException 实际上更可取。在这种情况下,抛出 NullPointerException 是实际上期望的结果。编写 "防御性" 代码并使用 null 引用意味着调用方的代码被破坏,但从未发现这一点。用户无法输入 null,这意味着代码已经损坏,因此应该抛出异常。 - Ande Turner
如果(n != null && !"".equals(n)) - MattC
或者如果你想要冗长一些(我因为这个被喊过),可以写成 if (n != null && !n.equals("")) - MattC

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

如果n不是空字符串,则将其值赋给name。

在Java中,每个对象都有一个equals(Object o)方法,用于测试与另一个对象的相等性。==运算符通常用于比较基本类型。它也可以用于比较对象的“sameness”,即两个对象实际上是同一实例。这对于不可变类型(例如字符串)和所有原始类型的对象包装器(例如Integer和Long)非常方便。


1
这不是不好的形式吗?使用 n.length() > 0 不是更好吗? - Chris K
3
与其它字符串进行比较可能会更清晰,你可以选择你感兴趣(或不感兴趣)的特定字符串。 !n.isEmpty() 可能更好。实际上,对于非法值最好抛出一个 IllegalArgumentException 异常。 - Tom Hawtin - tackline

3

equals() 方法比较两个字符串的内容。== 和!= 运算符告诉您两个String对象是否为同一对象。即使是具有相同内容(因此equals()相互等于)的两个不同字符串,它们仍可能彼此不等。尽管字符串不可变,但通过想象字符串是可变的来理解差异会有所帮助,然后equals()表示“当前相同”,==表示“始终相同”。

安全规则是始终使用equals(),除非您确定两个字符串都是interned。引用:

因此,对于任何两个字符串s和t,当且仅当s.equals(t)为true时,s.intern() == t.intern()为true。

所有文字字符串和字符串值常量表达式都是interned。


1

考虑一下:

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

变量a和b都是字符串对象,每个对象都有自己的内存分配,因此具有唯一的地址。a和b位于不同的地址。当您编写布尔表达式时

a == b

你正在比较对象的地址,而不是它们的内容。要比较内容,必须使用String对象的equals()方法。

一个对象在内存中有一个物理位置,每个对象都是唯一的 -- 没有两个不同的对象可以有相同的内存地址 -- 并且有其内容或值。==运算符比较对象的地址;当你编写a==b时,你正在询问a和b是否是同一个对象的别名 -- a和b是否引用同一个物理位置。a.equals(b)询问两个对象是否具有相同的值,无论它们在哪里。

这在编译器的“内部化”中有些复杂,编译器可能会在编译时检测到两个常量具有相同的值并重用同一个对象,但对于在运行时创建的值来说,这并不成立。


好的...那么比较对象和地址有什么区别呢?a==b和a.equals(b)不同吗?(虽然我可能刚刚把这行搞砸了,但我并不完全理解它,这就是为什么我在这里发帖的原因。) - Soully
2
实际上,它们是相同的 - 编译时常量字符串被内部化。 - Tom Hawtin - tackline
一个对象在内存中有一个物理位置,每个对象的位置都是唯一的 -- 没有两个不同的对象可以具有相同的内存地址 -- 以及它的内容或值。 "==" 运算符比较对象的地址;当你编写 a==b 时,你是在询问 a 和 b 是否是同一个对象的别名 -- a 和 b 是否引用同一个物理位置。a.equals(b) 询问这两个对象是否具有相同的值,无论它们在哪里。 - Jim Garrison
你代码中的a和b不是对象,它们是变量。a指向与b完全相同的对象,因此在该代码中a == b返回true!编译器将相同(内部化)的字符串分配给两者。试一试吧!如果要创建一个新的字符串,可以尝试使用b = new String("")。 - user85421

0

equals() 方法将返回一个 boolean 值,该值说明传入的对象是否与调用该方法的对象“相等”。这个“相等”方法可以在类中被重写以进行自己的测试。对于 String,测试是原始字符串的值是否与传入的对象的字符串表示形式的值相同。

由于它返回一个布尔值,因此您可以使用 ! 取反该值,因此测试是“方法参数不是空字符串吗?” 是的?然后将其分配给我们的 name 变量。

== 将始终测试左侧的对象是否与右侧的对象相同,因为它比较引用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接