为什么StringBuilder在使用空字符后停止添加元素?

12

当我使用空字符'\u0000'时,字符串构建器将停止添加新元素。

例如:

StringBuilder _stringBuilder = new StringBuilder();
_stringBuilder.append('\u0000');
_stringBuilder.append('a');
System.out.println("."+_stringBuilder+".");

返回

. 

我知道空值不应该被打印出来(或者像空的字符串值一样打印出来),但在这种情况下,为什么 StringBuilder 无法添加更多元素呢?

注意:我正在使用 Ubuntu 上的 jdk 1.6.0_38。


'\0' - 空终止符,在 C 和 C++ 字符串中用作字符串的结尾 - user1516873
1
我怀疑 StringBuilder 已经停止添加新元素。更可能的是在显示结果 String 时出现了问题。在添加几个元素后,StringBuilderlength() 是多少? - Bill the Lizard
1
我在Win 7上使用jdk 1.6.0_25在eclipse中运行了您的代码,它打印出. a....可能是特定于shell的事情。 - FGreg
1
我认为这是与操作系统有关的问题,因为Java字符串可以包含空字符。在这里,Win7打印相同的内容。 - Brian
1
在这里打印.a.:http://ideone.com/BjRKT0 - wirey00
3个回答

7
您的stringBuilder仍在添加元素,如下所示:
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append('\u0000');
System.out.println(stringBuilder.length()); // prints 1
stringBuilder.append('a');
System.out.println(stringBuilder.length()); // prints 2

我的猜测是,您的控制台在遇到终止字符\u0000后停止打印。不同的控制台可能会有不同的处理方式。

7

空字符是一个保留字符,用于表示字符串的结尾。如果你在打印字符串后面加上 \u0000,那么在此字符后面的内容都不会被打印出来。


为什么使用空字符后,StringBuilder停止添加元素?这并不是Java的问题,而是您的终端将\u0000视为字符串的结尾。

有人说,在Windows下输出可能是.a.(我没有测试过),这是因为Windows终端与基于Unix的系统终端的工作方式不同。我非常确定,如果您在OSX机器上运行此代码,您将获得与在Linux上获得的相同输出。


2
它在我的Windows机器上打印了一个“.”,一个方框(表示空字符),一个“a”和一个“.”。 - Bhesh Gurung
@BheshGurung 我认为这是因为UNIX系统与Windows工作方式不同,理论上,如果您在OSX上尝试相同的操作,它应该会打印“.”。 - BackSlash
2
在Java中,空字符不用于终止字符串。 - Kayaman
null是一个保留字符,它在哪里使用?无论是gnome-terminal、xterm还是rxvt都没有问题描述中所述的行为。它们都只是忽略null字符。 - Rotsor
@Rotsor \u0000 在类 C 语言中被用作字符串的标准结束方式,终端也曾经将其用作“字符串结束”的标志。需要注意的是,这个问题已经存在了将近四年的时间。Linux 不断发展,所以在这四年中可能已经有所改变。在问题发布时,该问题确实存在,但现在可能已经得到解决。而且,可能某些终端在 Linux 上仍然存在此问题。你的终端版本无法重现此问题并不意味着这个问题及其答案是错误的(除非你尝试了每一个终端/版本)。 - BackSlash
这就是为什么我在询问而不是说有什么问题。如果您知道一个可以做到这一点的终端,我很感兴趣。无论如何,仅仅说它是一个“保留”字符,而没有指定哪个软件使其保留,这并不是一个非常好的答案。 - Rotsor

1

我尝试了您的测试,在我的Windows 7系统上在Eclipse中没有失败。但是,运行此测试程序将区分非追加和非打印。我建议在失败环境中运行它。

public class Test {
  public static void main(String[] args){
    StringBuilder _stringBuilder = new StringBuilder();
    _stringBuilder.append('\u0000');
    _stringBuilder.append('a');
    System.out.println("."+_stringBuilder+".");
    System.out.println(_stringBuilder.length());
    System.out.println(_stringBuilder.charAt(1));
  } 
}

如果问题是非追加,长度将小于2,并且尝试在索引1处打印字符将失败。如果问题是非打印,则长度为2,索引1处的字符将为'a'。
我认为非打印比非追加更有可能发生。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接