서식문자 관련 문제를 풀다가, 다른 사람들이 해결한 방법을 찾던 중
System.out.println(String.format(format,args));
형태의 코드를 보게 되었다.
이때까지 printf()로 풀고 있었는데 뭐가 다른가? 하고 궁금해서 찾아보게 되었는데, f3과 번역 콤보, 구글링으로 공부해 본 결과 변수를 정렬하여 출력할 수 있는 메소드로 printf()와 동일한 것 같다. (설명 주석으로 C의 printf()의 영향을 크게 받았다고 되어 있다.)
나는 예전에 c를 해본 적도 있고, java를 맨 처음 배웠을 때 서식문자를 사용해 출력하는 방법에 대해 printf()를 접해본 적이 있었는데 그 때 가르쳐주셨던 교수님께서 java의 printf()는 c언어 개발자의 접근성을 높이는 하나의 수단(?)으로 있는 것이라고 말씀 하셨던 것 같다.
F3을 통해 확인해본 String.format()과 System.out.printf()
1. String.format()
public static String format(String format, Object... args) {
return new Formatter().format(format, args).toString();
}
String.format()의 경우 Formatter객체의 format() 메소드를 가지고 원하는 결과 형태로 바꾼 후 toString() --> 문자열로 변환됨
2. System.out.printf()
public PrintStream printf(String format, Object ... args) {
return format(format, args);
}
여기서 format메소드는 같은 PrintStream 클래스 안의 format 함수로,
public PrintStream format(String format, Object ... args) {
try {
synchronized (this) {
ensureOpen();
if ((formatter == null)
|| (formatter.locale() != Locale.getDefault()))
formatter = new Formatter((Appendable) this);
formatter.format(Locale.getDefault(), format, args);
//formatter 변수 역시 위에서 private Formatter formatter 로 변수 선언 되어 있음.
}
} catch (InterruptedIOException x) {
Thread.currentThread().interrupt();
} catch (IOException x) {
trouble = true;
}
return this;
}
똑같이 Formatter 객체를 생성(new)하고 Formatter 객체의 format()를 사용한다.
그렇다면 Formatter 객체의 format()은 어떤 역할일까?
3. Formatter 클래스의 format()?
public Formatter format(String format, Object ... args) {
return format(l, format, args);
}
위의 format()은 같은 Formatter클래스 내의 format() 메소드를 사용한 것이다.
public Formatter format(Locale l, String format, Object ... args) {
ensureOpen();
//ensureOpen() == formatting된 결과를 담을 Appendable 인터페이스 변수가 null이면 Exception이 발생되도록 되어있음.
//즉, null인지 먼저 체크한다
// index of last argument referenced
int last = -1;
// last ordinary index
int lasto = -1;
FormatString[] fsa = parse(format);
for (int i = 0; i < fsa.length; i++) {
FormatString fs = fsa[i];
int index = fs.index();
try {
switch (index) {
case -2: // fixed string, "%n", or "%%"
fs.print(null, l);
break;
case -1: // relative index
if (last < 0 || (args != null && last > args.length - 1))
throw new MissingFormatArgumentException(fs.toString());
fs.print((args == null ? null : args[last]), l);
break;
case 0: // ordinary index
lasto++;
last = lasto;
if (args != null && lasto > args.length - 1)
throw new MissingFormatArgumentException(fs.toString());
fs.print((args == null ? null : args[lasto]), l);
break;
default: // explicit index
last = index - 1;
if (args != null && last > args.length - 1)
throw new MissingFormatArgumentException(fs.toString());
fs.print((args == null ? null : args[last]), l);
break;
}
} catch (IOException x) {
lastException = x;
}
}
return this;
}
즉, Formatter의 format() 메소드는 출력 양식을 결정하는 역할이라고 할 수 있다.
그러므로 String.format()과 printf()는 둘 다 특정한 출력 양식을 정해 출력할 때 사용.
String.format()은 문자열화 시킨 것을 String형 변수에 바인딩 시킬 수 있다(String 형 결과가 return됨).
Formatter.format(args).toString();System.out.printf()는 문자열화 시킨 것을 PrintStream으로 바로 출력되도록 할 수 있다.
Formatter.format(args);
이처럼, 차이라고 한다면 String 형 변수에 바인딩 시킬 수 있냐(String.format()) 없냐, 바로 출력시키느냐(System.out.printf()) 아니냐로 나뉠 수 있겠다.
1줄요약 : 출력만 할거면 똑같다.
'study_algorithm > 문제풀면서 알게된 것들' 카테고리의 다른 글
Scanner 와 BufferedReader, 그리고 BufferedWriter (0) | 2024.08.13 |
---|---|
String, StringBuffer, StringBuilder (0) | 2020.11.28 |