null 은 누가찍나?
Java 에서 System.out.println(null 변수); 를 하면 null이 찍힌다.
System.out , PrintStream 은 다양한 println 오버로딩 메소드들이 존재한다.
표준출력 하기 위해 println(Object)메소드를 사용해보자.
primitive 타입이 아닌 Object의 경우 아래와 같이 String.valueOf()메소드를 통해 인자가 null일경우 “null” 문자열을 리턴하고, null이 아니면 인자객체의 toString()메소드를 호출하여 리턴한다.
/**
* Prints an Object and then terminate the line. This method calls
* at first String.valueOf(x) to get the printed object's string value,
* then behaves as
* though it invokes <code>{@link #print(String)}</code> and then
* <code>{@link #println()}</code>.
*
* @param x The <code>Object</code> to be printed.
*/
public void println(Object x) {
String s = String.valueOf(x);
synchronized (this) {
print(s);
newLine();
}
}
String.class
/**
* Returns the string representation of the {@code Object} argument.
*
* @param obj an {@code Object}.
* @return if the argument is {@code null}, then a string equal to
* {@code "null"}; otherwise, the value of
* {@code obj.toString()} is returned.
* @see java.lang.Object#toString()
*/
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
음?
그런데 println(Object x) 메소드에서는 print(Object obj) 메소드가 존재하는데도.
왜 굳이 String.valueOf를 호출해서 String 값을 구한 후에 print(String s)로 넘기는 걸까?
print(Object obj) 는 Object를 인자로 받고 내부적으로 String.valueOf() 메소드도 호출하고 있는데 말이다.
public void print(String s) {
if (s == null) {
s = "null";
}
write(s);
}
public void print(Object obj) {
write(String.valueOf(obj));
}
println(Object x) 메소드를 보면 인자에 대해 String.valueOf를 호출하는 부분이 synchronized 블럭 바깥에 존재한다.
성능을 위해 동기화 할 필요 없는 String.valueOf 메소드 호출을synchonized 블럭 바깥으로 뺀것이 아닐까 생각한다.
그렇기 때문에 synchronized 블럭 내에서는 print(Object obj)를 사용하지 않고 print(String s) 메소드를 사용 하는 것으로 보인다.
jetbrain 에 계시는 듯한 분이 답을 달아줬는데.
교착상태를 피하기 위해서하고 한다.
syncrhonized 블럭 내의 static method 호출이 교착상태에 빠지게 할수 있는지는 더 찾아봐야겠다.
샛길로 빠졌다.
null변수의 출력시 “null” 문자열을 리턴하는 주체는
print(String s) 에서는 String.valueOf 를 호출하지 않고 null체크 한다.
.. 이유는 위와 같을것 같기도 하고.. 생각 중.