1

我有一个用 Java 和 C# 编写的简单递归方法

爪哇

public static String reverse(String letter) {
    if (letter == "")
        return "";
    else
        return letter.substring(letter.length() - 1)
                + reverse(letter.substring(0, letter.length() - 1));
}

C#

public static string reverse(string letter)
{
    if (letter == "")
        return "";
    else
        return letter[letter.Length - 1]
                + reverse(letter.Substring(0, letter.Length - 1));
}

但是 Java 版本在 时失败letter == "",即使字母为空,它也会返回 false。为什么 C# 版本可以工作,而 Java 版本失败?

4

9 回答 9

6

在 C# 和 Java 中,运算符默认==检查引用相等性。

但是,在 .NET 中,==运算符被重载string以检查值是否相等:

public static bool operator ==(string a, string b)
{
    return string.Equals(a, b);
}

使用这两种语言时需要考虑的另一个因素是字符串暂留,它甚至可以导致可能出现不同的字符串的引用相等成功。来自MSDN(对于 C#):

公共语言运行时通过维护一个称为实习池的表来保存字符串存储,该表包含对程序中以编程方式声明或创建的每个唯一文字字符串的单个引用。因此,具有特定值的文字字符串的实例在系统中只存在一次。

例如,如果您将相同的文字字符串分配给多个变量,则运行时会从实习池中检索对文字字符串的相同引用并将其分配给每个变量。

字符串实习适用于 Java 和 C#,通常会提供一致的结果。例如,两种语言都在编译时评估字符串连接,这意味着"a" + "b"存储为"ab"

"ab" == "a" + "b"                                      // Java: Gives true
object.ReferenceEquals("ab", "a" + "b")                // C#:   Gives true

但是,当获取长度为零的子字符串时,只有 C# 返回内部空字符串:

"" == "abc".substring(0, 0)                            // Java: Gives false
object.ReferenceEquals("", "abc".Substring(0, 0))      // C#:   Gives true
于 2012-06-16T15:53:42.727 回答
5

因为对于对象,运算符 ==测试引用的相等性。您必须始终使用equals

于 2012-06-16T15:42:52.930 回答
4

字符串是一个对象。

当您使用 时==,您正在进行身份比较。这意味着这a == b是在询问a和是否b是同一个对象。

变量letter和常量对象""不是同一个对象,所以你得到错误。

相反,您应该使用:

letter.equal("")

这是询问letter对象是否具有等于 的值"",这就是您要问的意思。

于 2012-06-16T15:44:21.527 回答
3

有几种方法可以做到这一点:

  1. 为了比较 Java 中的字符串,我们必须使用.equals()or.equalsIgnoreCase()方法。... if (letter.equals("")) { ...
  2. 检查长度可以判断此字符串长度是否为 0。... if (letter.length() == 0) { ...
  3. (letter.length() == 0)在 Java 中有等价的 for 。那就是.isEmpty()方法。

顺便说一句:
别忘了if (letter == null)

于 2012-06-16T15:42:05.037 回答
2

在java==中比较两个变量是否包含相同的对象。常量""可能始终是 String 的不同实例,即使两个实例可能包含相同的字符串值。

如果你想比较对象的内容,那么对于字符串,你可以这样做:

字母.等于(“”)

于 2012-06-16T15:50:12.290 回答
1

在 Java 中,

运算符==比较变量中的值。

因此,在原始类型变量的情况下,它将起作用,因为变量中的值是原始类型的实际值。

例如

 int a = 1;
 int b = 2;

 if(a == b) { 

在上面它正在做你认为它正在做的事情。


但是,在引用类型变量的情况下,变量中的值是对它们所指向的对象的引用。

因此,如果您想进行身份检查(即您想查看两个不同的变量是否指向同一个对象),那么您必须使用==. 如果变量引用了两个不同的对象(对象的内容相同不相关),这将返回 false。

但是,如果您要尝试的是对象的内容,那么您必须使用equals方法(但您必须确保该equals方法已正确实现)。

例如

String a = "a";
String b = new String("a");

if(a == b) { //... identity check (returns false)

//...

if(a.equals(b)) { //... comparing the contents (returns true)
于 2012-06-16T16:03:59.093 回答
0

因为你在比较引用,使用String.equalsString.equalsIgnoreCase

于 2012-06-16T15:46:14.350 回答
0

您应该使用equals类似的方法,letter.equals("")因为相等运算符 ( ==) 最终比较对象的引用而不是值。

此外,更好的做法是C#使用string.Empty""

if (letter == string.Empty)
于 2012-06-16T15:48:09.343 回答
-1

== 适用于字符串对象((在 google 中查找字符串池 java),但您应该(并且必须)真正使用 .equals()。

于 2012-06-16T15:42:53.837 回答