public class ToStringMain {
public static void main(String[] args) {
Object obj = new Object();
String objString = obj.toString();
System.out.println(objString);
System.out.println(obj);
}
}
// 결과 java.lang.Object@4c873330
// 결과 java.lang.Object@4c873330
toString()을 통해 객체의 정보를 String으로 받은 결과와 객체를 바로 출력한 결과가 동일하다 어떻게 된 일일까?
// Object 클래스를 인자로 받았을 때 호출되는 println 메서드
public void println(Object x) {
String s = String.valueOf(x);
if (getClass() == PrintStream.class) {
// need to apply String.valueOf again since first invocation
// might return null
writeln(String.valueOf(s));
} else {
synchronized (this) {
print(s);
newLine();
}
}
}
// 그 중 활용되는 valueOf 메서드
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
Object 객체를 인자로 받았을 때, obj.toString()의 결과를 호출하고 있는 것을 알 수 있다
따라서 toString() 호출을 할 필요 없이 바로 객체를 전달해도 된다.
그렇다면 toString() 메서드를 호출할 일은 없을까?
toString() 오버라이딩
사실 현재 toString() 메서드가 반환해주는 값은 객체의 정보를 파악하기에 그다지 도움이 되지 않는 정보들이다.
따라서 오버라이딩을 통해 객체가 갖고 있는 정보 중 원하는 것들을 출력하도록 수정하면 된다
public class Dog {
private String dogName;
private int age;
public Dog(String dogName, int age) {
this.dogName = dogName;
this.age = age;
}
// 원하는 스타일로 커스텀
// @Override
// public String toString() {
// return "dogName : " + dogName + ", age : " + age;
// }
// IDE 기본 제공
@Override
public String toString() {
return "Dog{" +
"dogName='" + dogName + '\'' +
", age=" + age +
'}';
}
}
System.out.println() 과 toString()
만약 Object 클래스가 없고, toString() 메서드도 없었다면 개발자들은 직접 각 클래스별로 toString() 메서드를 선언해줘야했기 때문에 서로 다른 객체의 정보를 출력하기 어려웠을 것이다
이런점에서 현재 println() 메서드는 다형성을 잘 활용하고 있다
다형적 참조 : Object 클래스를 매개변수 타입으로 선언함으로서 모든 객체를 인자로 받을 수 있다
toString() 메서드 오버라이딩 : 인자로 들어오는 인스턴스가 toString() 메서드를 오버라이딩 했다면 런타임 시점에 해당 인스턴스의 toString()을 호출할 수 있게 된다
따라서 println() 메서드는 구체적인 타입에 의존을 하지 않고도 구현체의 메서드를 호출할 수 있는 것이다