关于对象标识和对象平等以及String类异常的问题

时间:2009-12-01 07:26:14

标签: c# java identity equality

这是一个Java和C#问题。 我们都知道,对象标识(==)测试两个对象是否引用相同的位置,并且Obejct Equality(Equals方法)测试两个不同(不相同)的对象是否具有相同的值。但是在字符串对象的对象标识和对象平等是相同的。 例如,if语句中的两个布尔表达式返回true

string a="123";
string b="123";
if(a==b)
if(a.Equals(b))

为什么会这样? 这个设计决定背后的理性是什么?

4 个答案:

答案 0 :(得分:4)

Java和C#都使用称为string interning的内存节省技术。因为字符串在这些语言中是不可变的,所以它们可以汇集经常使用的字符串(包括硬编码的字符串文字,如示例中所示),并在内存中使用多个引用来保存空间。

答案 1 :(得分:3)

据我所知,在.net中,==字符串运算符被重载以使用Equals()而不是对象标识。有关详细信息,请参阅此说明:http://www.dotnetperls.com/string-equals

如果你需要知道它是否真的是同一个对象,请使用:

Object.ReferenceEquals(string1, string2)

答案 2 :(得分:2)

实际上,至少在Java中,字符串上有一个缓存机制。一个陷阱是两个相等的字符串有时会,但在应用标识运算符时并不总是返回true。以下代码打印为false:

String a="123";
String b="12";
b=b+"3";
System.out.println(a==b);

答案 3 :(得分:0)

如果你真的想确定,a.equals(b) == true(a==b) == false对两个字符串a和b的求值为false,那么你可以使用完全被低估的(^^)字符串构造函数:

String a = new String("abc");
String b = new String("abc");
if (a.equals(b)) {
   doTheyAreEqual();
   if (a != b) {
     doButNotTheSame();
   }
}