부모 클래스에서 정의된 static메서드를 자식 클래스에서 똑같은 이름의 static메서드로 정의한다고 해서 오버라이딩은 아니다. 단지 각 클래스에서 별개의 static메서드를 정의한 것일 뿐이다.
protected Object clone() // 객체 자신의 복사본을 반환
public boolean equals(Object obj) // 객체 자신과 객체 obj가 같은 객체인지 확인
public Class getClass() // 객체 자신의 클래스 정보를 가지고 있는 Class 인스턴스를 반환
public int hashCode() // 객체 자신의 해시코드를 반환
public String toString() // 객체 자신의 정보를 문자열로 반환
public void notify() // 객체 자신을 사용하려고 기다리는 쓰레드를 하나만 깨움
public void notifyAll() // 객체 자신을 사용하려고 기다리는 쓰레드 모두 깨움
public void wait() // 다른 쓰레드가 notify()|notifyAll()를 호출할 때까지 대기
public class Student {
int id;
public static void main(String[] args) {
Student s1 = new Student();
Student s2 = new Student();
s1.id = 123456;
s2.id = 123456;
if(s1.equals(s2))
System.out.println("s1 == s2");
else
System.out.println("s1 != s1");
System.out.println(s1.hashCode());
System.out.println(s2.hashCode());
System.out.println(s1.toString());
// 실행결과
// s1 != s2
// 747464370
// 1513712028
// Student@2c8d66b2
}
}
위의 실행결과를 정리하자면 결론적으로 객체 s1과 객체 s2는 같지 않다. 즉, 객체가 저장되어있는 메모리 주소가 같지 않다는 것이다. 따라서 주소값으로 만드는 해시코드도 같지 않다.
public boolean equals(Object obj) {
return (this == obj);
}
@Override
public boolean equals(Object obj) {
return (this.id == ((Student) obj).id);
}
클래스의 인스턴스변수 값으로 객체의 같고 다름을 판단해야 할 경우, equals메서드 뿐 만아니라 hashCode메서드도 Overriding 해야 한다.
String 클래스는 문자열의 내용이 같으면 동일한 해시코드를 반환하도록 hashCode메서드가 오버라이딩 되어 있다. 반면에 System.identityHashCode(Object x)는 Object클래스처럼 객체의 주소값으로 해시코드를 생성해 모든 객체에 대해 항상 다른 해시코드값을 반환한다.
인스턴스 내부의 값 정보를 알고 싶다면 재정의를 통해 toString메소드를 사용한다.
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
@Override
public String toString() {
return "Student [id = " + id + "]";
}
@ToString
public class Student {
int id;
... 생략
}
@ToString
을 통해 따로 코드로 재정의하지 않아도 편리하게 재정의할 수 있다.
참고 : 자바에서 toString 메소드는 기본적으로 각 API 클래스마다 자체적으로 오버라이딩을 통해 재정의되어있다. ex) String, Class, Arrays ...
참고: toString()과 String.valueOf() 모두 Object 클래스의 값을 String 클래스로 변환한다. Object가 null인 경우 toString()는
Null PointerException
을 발생시키지만 String.valueOf()는null
값을 반환한다.