Java中的字符串比较……?
可能重复:
如何比较Java中的字符串?
为什么第一次比较(s1 == s2)显示相等而第二次比较(s1 == s3)显示不相等….?
public class StringComparison { public static void main( String [] args) { String s1 = "Arsalan"; String s2 = "Arsalan"; String s3 = new String ("Arsalan"); if ( s1 == s2 ) System.out.println (" S1 and S2 Both are equal..."); else System.out.println ("S1 and S2 not equal"); if ( s1 == s3 ) System.out.println (" S1 and S3 Both are equal..."); else System.out.println (" S1 and S3 are not equal"); } }
这与您无法将字符串与==
以及编译器优化进行比较这一事实有关。
==
在Java中仅比较双方是否引用同一对象的完全相同的实例。 它没有比较内容。 要比较字符串的实际内容,您需要使用s1.equals(s2)
。
现在s1 == s2
为真且s1 == s3
为假的原因是因为JVM决定优化代码以使s1
和s2
是同一个对象。 (它被称为“String Pooling。”)
根据3.10.5:字符串文字的汇集实际上是由标准强制执行的。
此外,字符串文字始终引用类String的相同实例。 这是因为字符串文字 – 或者更常见的是作为常量表达式(第15.28节)的值的字符串 – 被“实例化”以便使用String.intern方法共享唯一实例。
不要使用==
来比较字符串,它测试引用相等性(做两个名称引用同一个对象)。 尝试s1.equals(s2);
,实际上测试元素是否相等。
String one = "Arsalan"; String two = "Arsalan";
-
一个==两个
//返回true,因为在内存中两个字符串都指向SAME对象
-
one.equals(二)
//总是会返回true,因为字符串的值是相同的(如果对象被不同地引用则无关紧要)。
原因是字符串实习 。 情况很复杂。 编译器“智能”足以对s1和s2使用相同的确切对象,即使您可能认为它们不同。 但是使用new String("Arsalan")
s3并不是实习生。
一些准则:
- 您应该几乎总是使用equals()而不是==来比较字符串
- 你几乎不应该使用
String s = new String("foo")
。 相反,使用String s = "foo"
。
如果在字符串池中找不到“Arsalan”,则会创建“Arsalan”字符串,s1将引用它。 由于“Arsalan”字符串已经存在于字符串池中,因此s2将引用与s1相同的Object。 因为new关键字用于s3,Java将在普通(非池)内存中创建一个新的String对象,而s3将引用它。 这就是为什么s1和s3不引用同一个对象的原因。
public class StringComparison { public static void main( String [] args) { String s1 = "Arsalan"; String s2 = new String("Arsalan"); String s3 = new String ("Arsalan"); if ( s1 == s2 ) System.out.println (" S1 and S2 Both are equal..."); else System.out.println ("S1 and S2 not equal"); if ( s1 == s3 ) System.out.println (" S1 and S3 Both are equal..."); else System.out.println (" S1 and S3 are not equal"); if ( s2 == s3 ) System.out.println (" S2 and S3 Both are equal..."); else System.out.println (" S2 and S3 are not equal"); } }
如果你运行它,你可以看到S2和S3也不相等。 这是因为s2,s3是对String对象的引用,因此它们包含不同的地址值。
不要使用==
,而是使用s1.equals(s2)
或s1.equals(s3)
。
- 有关j_security_check,j_username和j_password的Servlet安全性问题
- Android:如何获取绘制路径的区域大小?
- 从libgdx中的集合中检测触摸对象(移动)的最佳方法
- 线程“main”中的exceptionjava.lang.NoClassDefFoundError:org / codehaus / jackson / JsonParseException
- Android – Java Stack vs Native Stack
- 序列化中参考共享的含义是什么? 枚举如何序列化?
- 如何在java中将文件读入字符串?
- android.view.ViewRoot $ CalledFromWrongThreadException:
- 在java中解析JSON