4

我编写了以下程序。

public class StringTest {
    public static void main(String[] args){
        String x = "\0";
        String y = " ";
        System.out.println("This is x - "+x+".");
        System.out.println("This is y - "+y+".");
        System.out.println(x.equals(y));
    }
}

当然x.equals(y)应该清楚false,因为它们是完全不同String的s。然而,输出让我感到惊讶。

This is x -  .
This is y -  .
false

如果这两个Strings 不相等,那么它们如何产生相同的输出?

4

7 回答 7

11

如果这两个字符串不相等,那么它们如何产生相同的输出?

它们看起来像相同的输出......在您的控制台上!

如果您将控制台输出重定向到一个文件并使用十六进制转储工具进行检查,您可能会1发现它们不同。

1 - 我们无法确定。平台默认字符集中的字符编码过程也可能是将 NUL 映射到 SP。但是十六进制转储会澄清这一点。


顺便说一句,nullJava中的“空文字”是人们正常的意思。你所拥有的是一个String文字......其唯一的字符是 Unicode code-point 0x0000

于 2013-07-12T12:50:40.447 回答
2

具有相同的输出(光学)并不意味着字符串由相同的字符组成。例如,一个制表符看起来与四个空格相同。在 UTF-8 中,有很多字符看起来完全相同,但实际上并非如此。

这也可能仅适用于控制台上的表示。即使空字符看起来不同,您的控制台也可能会错误地显示它。

于 2013-07-12T12:50:16.720 回答
1

我为 32 个控制字符 + 空格做了这个:

    try (PrintWriter out = new PrintWriter("C:/ctl.txt")) {
        for (int i = 0; i <= 32; ++i) {
            String s = "" + (char)i;
            System.out.println("(char)" + i + " is '" + s + "'.");
            out.println("(char)" + i + " is '" + s + "'.");
        }
    } catch (FileNotFoundException ex) {
        Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex);
    }

除了退格、制表符、换行和回车之外,IDE 控制台还显示了一个空格。在文件中,控制字符在那里。因此,将非功能控制字符显示到空格是一个问题。

于 2013-07-12T13:05:43.467 回答
1

Java 程序的实际输出是

This is x - 
This is y -  .
false

编辑:请注意,这可能非常依赖于操作系统和控制台,因为 \0 在许多技术中都是字符串终止符。

于 2013-07-12T12:50:32.023 回答
0

Stings 是不一样的,即使它们在打印到控制台时看起来相同。

打印到控制台会为字符串添加额外的处理。(将字节转换为屏幕上的像素)。在您的情况下,它将 \0 字符转换为空格。

看看 DrYap 发布的链接,ideone.com/wWEv2v。他的输出看起来和你的不一样。

于 2013-07-12T12:52:41.330 回答
0

尽管字符串不相等,以下如何产生相同的输出?

System.out.println("x\bA");
System.out.println("y\bA");
System.out.println("A");
于 2013-07-12T13:08:05.200 回答
0

您看到的是控制台应用程序的局限性。二进制 0 在显示屏上看起来与空格字符相同。如果您想查看差异,则必须查看字符串的内存转储。

于 2013-07-12T12:53:44.107 回答