item12를 들어가면 곧 바로 간결하면서 사람이 읽기 쉬운 형태의 유익한 정보
를 반환해야 한다. 는 문장을 볼 수 있다. 이는 이후에 보여줄 Enum의 toString()메소드의 문서 주석에 나오는 programmer-freindly
키워드와 동일한 의미를 가진다고 생각한다.
결국 이번 item12을 정리하게 되면 toString()메소드의 재정의 기준이 이 programmer-freindly에 맞춰서 재정의한다.
인 것 같다. 따라서 이번 게시글은 item12을 공부하며 알게된 여러 클래스의 toString()에 대해 조금 적어보겠다.
우선 책을 보면 대다수의 컬렉션 구현체는 추상 컬렉션 클래스들의 toString()메소드를 상속해 쓴다
고 되어있다. 그럼 흔히 사용하는 HashMap과, HashSet을 확인 해 보자. Enum의 toString() 메소드도 확인해 볼 것이다.
HashMap은 AbstractMap을 상속받고있다. 그리고 실제로도 HashMap클래스에는 toString()이 재정의 되어있지 않고, AbstractMap의 toString()
을 그대로 사용하고 있음을 확인 할 수 있다.
그리고 여러 Map의 구현체, WeakHashMap, TreeMap, LinkedHashMap, EnumMap 들도 AbstractMap의 toString()을 사용하고 있다.
AbstractMap의 toString()은 다음과 같다.
public String toString() {
Iterator<Entry<K,V>> i = entrySet().iterator();
if (! i.hasNext())
return "{}";
StringBuilder sb = new StringBuilder();
sb.append('{');
for (;;) {
Entry<K,V> e = i.next();
K key = e.getKey();
V value = e.getValue();
sb.append(key == this ? "(this Map)" : key);
sb.append('=');
sb.append(value == this ? "(this Map)" : value);
if (! i.hasNext())
return sb.append('}').toString();
sb.append(',').append(' ');
}
}
toString()을 출력해보면 우리에게 익숙한 형태임을 알 수 있다.
HashSet은 AbstractSet을 상속받고 있다. 그리고 AbstractSet은 AbstractCollection을 상속받고 있다. 그래서 이 AbstractCollection의 toString()
메소드를 사용하게 된다.
AbstractCollection의 toString()메소드는 다음과 같다.
public String toString() {
Iterator<E> it = iterator();
if (! it.hasNext())
return "[]";
StringBuilder sb = new StringBuilder();
sb.append('[');
for (;;) {
E e = it.next();
sb.append(e == this ? "(this Collection)" : e);
if (! it.hasNext())
return sb.append(']').toString();
sb.append(',').append(' ');
}
}
HashSet, LinkedHashSet, TreeSet등을 확인 해보자.
toString()을 출력해보면 Set도 익숙한 형태로 보여진다.
java.lang패키지에 있는 Enum클래스의 toString()은 다음과 같다.
/**
* Returns the name of this enum constant, as contained in the
* declaration. This method may be overridden, though it typically
* isn't necessary or desirable. An enum type should override this
* method when a more "programmer-friendly" string form exists.
*
* @return the name of this enum constant
*/
public String toString() {
return name;
}
단순히 name을 반환하고 있다. 문서 주석을 보면 잘 재정의 하지는 않지만, programmer-friendly한 string이 있는 경우 재정의된다.
고 되어있다. 이번 item12와 연결지어 간결하면서 사람이 읽기 쉬운 형태의 유익한 정보
의 형태가 바로 programmer-freindly
정도로 이해할 수 있을 것이다.
여기서 한번 생각해 볼만한 점은 toString()메소드가 단순히 name를 반환하고 있고, Enum클래스에는 name()이라는 메소드도 존재하는데 이 또한 단순히 name을 반환 해주고 있다.
/**
* Returns the name of this enum constant, exactly as declared in its
* enum declaration.
*
* <b>Most programmers should use the {@link #toString} method in
* preference to this one, as the toString method may return
* a more user-friendly name.</b> This method is designed primarily for
* use in specialized situations where correctness depends on getting the
* exact name, which will not vary from release to release.
*
* @return the name of this enum constant
*/
public final String name() {
return name;
}
문서주석을 보면 toString()메소드는 좀 더 user-freindly한 name을 반환해줄 것 이고, name()메소드는 정확한 name비교 등에 사용될 것 이다.
라는 것을 볼 수 있다. 다시 말하면 name()메소드는 final키워드가 붙어 더이상 재정의를 할 수 없고, toString()은 재정의가 가능하다. 따라서, 필요에 맞게 toString()을 재정의하여 name을 출력하게끔 사용하게 될 것이다.
effective-java스터디에서 공유하고 있는 전체 item에 대한 정리글