Java Prinf에서 \n 이냐 %n이냐?

사당동씩씩이·2023년 11월 16일
post-thumbnail

문자열 출력에 대한 테스트 코드를 작성하여 사용하던 중
System.out.printf("안녕\n");
System.out.printf("안녕%n");
두가지의 출력문이 눈으로 테스트 하면 동일하지만 코드상 다르다는 것은 알고 있다.
그럼 나는 무엇을 사용하는게 좋을까?

고민이 시작된 testcode는 아래와 같다.

private static final String LINE_SEPARATOR = System.lineSeparator();
private OutputStream captor;

@BeforeEach
void setUp() {
	captor = new ByteArrayoutputStream();
    System.setOut(new PrintStream(captor);
    String value = "안녕";
}


@Test
void escapeNTest() {
	System.out.printf("%s\n", value);
    assertThat(captor.toString().trim()).contains("안녕" + LINE_SEPARATOR);
}

@Test
void formatNTest() {
	System.out.printf("%s%n", value);
    assertThat(captor.toString().trim()).contains("안녕" + LINE_SEPARATOR);
}
  • 결과 : escapeNTest -> 실패, formatNTest -> 통과

왜?

  • 줄바꿈이 되는 것은 같은데 왜 lineSeparator()가 아닌가?
  • 답은 컴파일 할때 \n은 유니코드로 변환되어 저장되는데 있다.
  • escapeNTest 테스트 코드상 "안녕\n"에 "안녕"+lineSeparter()가 있는지 뭍는데 내 플랫폼이 window기 때문에 \r\n을 호출하여 실패한다. "안녕"이 포함되었는지 물어보게 되면 정상적으로 통과한다.

lineSeparator() 내부 들여다 보기

  • 이것은 java.base에 java.lang.system 의 내용이다.
/**
     * Returns the system-dependent line separator string.  It always
     * returns the same value - the initial value of the {@linkplain
     * #getProperty(String) system property} {@code line.separator}.
     *
     * <p>On UNIX systems, it returns {@code "\n"}; on Microsoft
     * Windows systems it returns {@code "\r\n"}.
     *
     * @return the system-dependent line separator string
     * @since 1.7
     */
    public static String lineSeparator() {
        return lineSeparator;
    }
  • 플렛폼 환경에 따라 줄바꿈이 다른것은 앞서 포스팅한 적이 있다. CRLF? LF?
  • 이것을 jvm에서 컴파일된 소스를 실행할 때, 플렛폼을 인식하고 적절하게 변환해주게 된다.

줄바꿈 테스트 하는 방법?

  • 당연하게도 플렛폼(운영체제)가 달라지면 결과가 달라지겠지만.. java코드라 볼 수 있을까?
  • 그렇기에 줄바꿈을 표현할 때는 lineSeparator()를 호출하는게 좋다.
  • %n 승리.
profile
N잡러 대충 이것저것 해보며 대충 사는 중

0개의 댓글