Java печатает массив символов

Я запускаю этот код и

char[] str = { 'a', 'b', 'c', 0, 'c', 'c', 'f' };
System.out.print(str);
System.out.println(" adksjfhak");

Это печатает только "abc". пока,

char[] str = { 'a', 'b', 'c', 0, 'c', 'c', 'f' };
System.out.print(str);
System.out.println("\n adksjfhak");

отпечатки

abc
 adksjfhak

Почему буфер печати останавливается на нулевом (0) символе? Означает ли это, что Java просто добавляет символ в буфер и печатает этот буфер? И, конечно же, поскольку этот буфер имеет 0 между ними, он отбрасывает остальную часть строки.

Наверное, я ответил на часть своего вопроса. Но хотелось бы узнать об этом подробнее. Как JVM справляется с этим? Где находится этот выходной буфер? И есть ли причина остановиться на 0? ТАКЖЕ, почему добавление \n останавливает это поведение?

Редактировать 1: Использование JDK 1.7, Eclipse 3.8.1 и Ubuntu 13.10

Редактировать 2: Как ни странно, у этого нет такой проблемы. https://ideone.com/VwFbRr

Редактировать 3: я выполнил то же самое в командной строке

[bin]$ java com.sakura.C 
abcccf adksjfhak

person sakura    schedule 06.04.2014    source источник
comment
У меня это отлично работает (JDK 1.7)   -  person Christian    schedule 06.04.2014
comment
@ Кристиан, ты имеешь в виду, что в первом случае ты получаешь и abc, и adksjfhak?   -  person sakura    schedule 06.04.2014
comment
Соответственно, у меня печатает abc ccf adksjfhak и abc ccf\n adksjfhak. Я не уверен, в чем проблема.   -  person Matthew    schedule 06.04.2014
comment
@sakura Я получаю "abcccf adksjfhak".   -  person Christian    schedule 06.04.2014
comment
@Christian Я также использую JDK1.7 + eclipse. Что-нибудь сделать с настройками консоли eclipse?   -  person sakura    schedule 06.04.2014
comment
@sakura Я не трогал конфигурации Eclipse, по крайней мере, чтобы ничего не настраивать для вывода/консоли. Может от ОС зависит?   -  person Christian    schedule 06.04.2014
comment
Не удается воспроизвести ваши результаты bit.ly/1idejXO   -  person Ari    schedule 06.04.2014
comment
Кто-нибудь пробовал пользоваться линуксом?   -  person sakura    schedule 06.04.2014


Ответы (2)


Поведение, которое вы видите, нельзя объяснить, взглянув только на код Java. Скорее, я подозреваю, что это как-то связано с тем, что вы используете для просмотра вывода.

Сначала это:

    char[] str = { 'a', 'b', 'c', 0, 'c', 'c', 'f' };
    System.out.print(str);

Согласно javadoc PrintWriter,

    System.out.print(str);

будет эквивалентно вызову

    System.out.print(str[i]);

для каждого персонажа. (Да каждый, включая нулевой символ!). И поведение write(char) заключается в том, чтобы просто кодировать символ в соответствии с кодировкой платформы по умолчанию и записывать его. Для нулевого символа (нулевая кодовая точка) и типичного 7- или 8-битного набора символов будет записан символ NUL.

На стороне Java нет фанковых "нулевых средств конца строки" со стандартными строками Java стандартных классов ввода-вывода Java. Период.

Я могу придумать 3 возможных объяснения:

  1. Вы ошибаетесь. Ваш фактический код пишет что-то другое. (Например, вы могли забыть перекомпилировать... если вы выполняете тестирование из командной строки.)

  2. Странное поведение, которое вы видите, происходит из-за того, что ваша консоль и/или утилита, которую вы используете для отображения вывода, делают что-то «особенное» с символами NUL. (Тем не менее, я не помню, чтобы я слышал о консольной программе и т. д., которая обрабатывала NUL таким странным образом...)

  3. Ваше приложение создало пользовательский подтип PrintWriter, который реализует некоторую специальную обработку нулевой кодовой точки, и оно использовало System.setOut(...) для перенаправления вывода через этот класс.


Сказав это, вероятно, плохая идея - пытаться печатать строки или массивы символов, которые содержат нулевые / NUL-символы. Символ NUL является «управляющим кодом» и обычно классифицируется как непечатаемый. То, что вы увидите, когда попытаетесь его распечатать,… непредсказуемо.

Если вы хотите продолжить это, я предлагаю вам перенаправить подозрительный вывод в файл, а затем использовать какую-либо (зависимую от ОС) утилиту для просмотра байтов файла; например od в системе Unix/Linux. Я ожидал увидеть нулевые байты в файле...

person Stephen C    schedule 06.04.2014
comment
Я думаю, что здесь должно быть 2. Это просто отдельный, единый класс. Но я использую JDK 1.7, Eclipse 3.8.1 и Ubuntu 13.10, что является довольно распространенной установкой. Также я ничего не делал с настройками JVM или какими-либо изменениями в Linux. - person sakura; 06.04.2014

Скорее всего, в обоих случаях все это «выводится» операционной системой, но в первом случае ваша операционная система или оболочка воспринимает символ «0» как сигнал не отображать остальную часть строки. В первом случае обе строки отображаются в одной строке, поэтому вторая строка также подавляется. Во втором случае вторая строка находится на новой строке и поэтому отображается.

person Warren Dew    schedule 06.04.2014
comment
Вы пробовали запускать код? Во всяком случае, проблема может заключаться в эмуляторе терминала, но, поскольку OP работает в Eclipse, это маловероятно. Как и другие, включая меня, которые пытались и не смогли воспроизвести проблему - в обоих случаях просто печатается «abcccf», без отображения вывода для символа 0. - person Erwin Bolwidt; 06.04.2014
comment
Да, похоже, линукс что-то здесь делает. Любые ссылки, кто-нибудь? - person sakura; 06.04.2014
comment
@ErwinBolwidt Символ 0 не является печатным символом, поэтому ожидается, что он не будет отображаться. - person Warren Dew; 06.04.2014