以下是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;
}
由于String是Serializable,在String.equals方法中使用==运算符是否有意义?如果我们尝试比较两个不同的String对象,可能是位于不同VM上的相同内存地址,这是否可以正常工作?
在我自己的代码中,我使用equals方法来比较两个字符串。我知道==做什么。我问的是在String类的equals方法中进行==比较是否有意义。
答案 0 :(得分:3)
使用==非常有意义,因为如果字符串的实例都指向相同的引用,则它们必须相等,因此不需要比较字符
答案 1 :(得分:1)
是的,这是有道理的,因为java使用了一个字符串池,因此当你创建一个不使用new关键字的String时,只要两个引用变量都相同,String ==将始终为true。
假设你的字符串池中有“”,如果你这样做
String a = "";
String b = "";
由于“”在字符串池中,它们实际上将指向相同的内存位置,因此
a == b
是真的
实际上只要你不使用
String c = new String("");
引用变量将始终指向String池中的“”。
但是,当您使用new关键字时,会在String池之外创建新的内存分配。因此,如果你这样做:
c == b
这将返回false,因为对b的引用在String池中,但c的引用不在,它在池外
但是,如果我们这样做了
String d = c.intern()
d == b
这将返回true,对于String类的注释是什么实习生
返回字符串对象的规范表示。 最初为空的字符串池由String类私有维护。
当调用intern方法时,如果池已经包含一个等于此String对象的字符串(由equals(Object)方法确定),则返回池中的字符串。否则,将此String对象添加到池中,并返回对此String对象的引用。
接下来,对于任何两个字符串s和t,当且仅当s.equals(t)为真时,s.intern()== t.intern()才为真。
正如一些人已经指出的那样,当对象在另一个JVM上反序列化时,它将使用该JVM字符串池
答案 2 :(得分:1)
Serializable表示可以使用Java的默认序列化机制将类的实例转换为字节并返回到对象实例中。反序列化对象时,将根据字节创建新的对象实例,并且该实例存在于JVM中,并在其中进行反序列化。序列化/反序列化不会神奇地使多个JVM中可以访问相同的对象实例,但它只是创建了彼此副本的新对象实例。
两个JVM无法共享对象实例,因此不可能使用==运算符来比较来自不同地址空间的对象实例的地址。
答案 3 :(得分:1)
java api中的这种IF情况是一种优化。因为虚拟机拥有一个字符串缓存并将一些(不是全部)字符串优化为文字。一些文字持有相同的对象引用。
使用我的JDK,例如
String a = "ABCD";
String b = "ABCD";
if (a==b)
等于true。因为两者都在我的jvm的Literal缓存中。但它还不足以比较对象引用,因为不是每个String都保存在文字缓存中。
e.g。
String a = new String("ABCD");
String b = new String("ABCD");
if (a==b)
将始终为false,因为您显式调用了新的对象引用。
但即使在上述情况下
if(a.intern()==b.intern())
也等于真。
答案 4 :(得分:0)
假设您正在谈论以下代码段:
if (this == anObject) {
return true;
}
使用==运算符是有意义的,因为只有当两个字符串都指向同一个内存地址时才会出现这种情况。这可能在java.lang.String中完成,以在使用字符串文字时优化字符串比较。您可以查看http://www.javaranch.com/journal/200409/ScjpTipLine-StringsLiterally.html以获取有关如何在Java中池化字符串文字的详细说明。
答案 5 :(得分:0)
如果我们尝试比较两种不同的 字符串对象,可能与之相同 内存地址,位于不同的地方 VM,这会正常工作吗?
你做不到。无论使用或不使用==运算符,都无法在两个VM中比较字符串。因此,您的问题不是关于任何事情。您必须将它们都放入同一个VM中,然后调用String.equals()。
== test只是一种速记,可以避免遍历所有其余的代码。它与序列化无关。不同的虚拟机不可能进入它。
答案 6 :(得分:-4)
没有。由于“String”不是主要类型,使用==只是比较对象的地址而不是内容本身。执行:
String a = "ABCD";
String b = "ABCD";
if (a == b)
你会得到假的,因为虽然字符串a&字符串b与它们在内存中的表示形式是不同的。
.equals()方法用于比较Java中的字符串(也称为Objects),因为它比较了Object的内容。