Object클래스
o Object클래스는 모든 클래스의 조상이기에 Object클래스의 멤버들은 모든 클래스에서 바로 사용이 가능하다.
o Object클래스는 멤버 변수 없이 오직 11개의 메서드만 가지고 있다. 이 메서드들은 모든 인스턴스가 가져야 할 기본적인 것들이다.
Object클래스의 메서드 | 설명 |
protected Object clone( ) | 객체 자신의 복사본을 반환한다. |
public boolean equals(Object obj) | 객체 자신과 객체 obj가 같은 객체인지 알려준다.(같으면 true) |
protected void finalize( ) | 객체가 소멸될 때 가비지 컬렉터에 의해 자동적으로 호출된다. 이 때 수행 되어야하는 코드가 있을 때 오버라이딩한다. (거의 사용안함) |
public Class getClass( ) | 객체 자신의 클래스 정보를 담고 있는 Class인스턴스를 반환한다. |
public int hashCode( ) | 객체 자신의 해시코드를 반환한다. |
public String toString( ) | 객체 자신의 정보를 문자열로 반환한다. |
public void notify( ) | 객체 자신을 사용하려고 기다리는 쓰레드를 하나만 깨운다. |
public void notifyAll( ) | 객체 자신을 사용하려고 기다리는 모든 쓰레드를 깨운다. |
public void wait( ) public void wait(long timeout) public void wait(long timeout, int nanos) |
다른 쓰레드가 notify( )나 notifyAll( )을 호출할 때까지 현재 쓰레드를 무한히 또는 지정된 시간(timeout, nanos)동안 기다리게한다. (timeout은 천분의 1초, nanos는 109 분의 1초) |
equals(Object obj)
o 매개변수로 객체의 참조변수를 받아서 주소 값으로 비교하여 결과를 boolean으로 알려준다.
o 두 객체의 같고 다름을 참조변수의 값으로 판단하기에 두 객체를 equals메서드로 비교하면 항상 false의 결과를 얻는다.
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
|
public class Test {
public static void main(String[] args) {
Value v1 = new Value(10);
Value v2 = new Value(10);
System.out.println(v1.equals(v2)?"v1과 v2는 같다.":"v1과 v2는 다르다.");
v1=v2;
System.out.println(v1.equals(v2)?"v1과 v2는 같다.":"v1과 v2는 다르다.");
}
}
class Value {
int value;
Value(int value) {
this.value = value;
}
}
|
- 두 Value의 인스턴스의 멤버 변수 value가 같더라도 equals는 주소 값으로 비교하기에 false의 결과가 나온다.
- 그러나 v1=v2;을 수행 후 v2의 주소 값이 v1이 참조하고 있는 인스턴스의 주소 값으로 변경되기에 equals의 결과가 true로 나온다.
public class Test {
public static void main(String[] args) {
Person p1 = new Person(8011081111222L);
Person p2 = new Person(8011081111222L);
System.out.println((p1==p2)?"p1과 p2는 같은 사람입니다.":"p1과 p2는 다른 사람입니다.");
System.out.println((p1.equals(p2))?"p1과 p2는 같은 사람입니다.":"p1과 p2는 다른 사람입니다.");
}
}
class Person {
long id;
Person(long id) {this.id=id;}
@Override
public boolean equals(Object obj) {
if(obj instanceof Person) {
//obj가 Object타입이기에 id값을 참조하기 위해서 Person타입으로 형변환이 필요하다.
return id==((Person)obj).id;
} else {
return false;
}
}
}
|
- equals메서드를 오버라이딩해서 주소가 아닌 객체에 저장된 내용을 비교하도록 변경하였다.
- 이렇게 함으로써 서로 다른 인스턴스 일지라도 같은 id를 갖고 있다면 true결과로 얻게 할 수 있다.
o String클래스 역시 Object의 equals메서드를 오버라이딩 하여 String인스턴스가 갖는 문자열 값을 비교하도록 되어있다.
o String클래스 뿐만 아니라 Date, File, wrapper클래스 (Integer, Double 등)의 equals메서드도 주소 값이 아닌 내용을 비교하도록 되어있다. 그러나 StringBuffer클래스는 오버라이딩 되어 있지 않다.
hashCode( )
o 이 메서드는 해싱(hashing)기법에 사용되는 ‘해시 함수(hash function)’를 구현한 것이다. 해싱은 데이터 관리 기법의 하나로 대량의 데이터를 저장하고 검색하는데 유용하다.
o 해시함수는 찾고자 하는 값을 입력하면, 그 값이 저장된 위치를 알려주는 해시코드를 반환한다.
o Object클래스에 정의된 hashCode메서드는 객체의 주소 값으로 해시 코드를 만들어 반환한다.
o 따라서 같은 객체라면 hashCode메서드를 호출했을 때 결과값의 해시 코드가 같아야 하기 때문에 클래스의 인스턴스 변수 값으로 객체의 같고 다름을 판단해야 한다면 equals메서드 뿐만 아니라 hashCode메서드도 오버라이딩을 해줘야 한다.
public class Test {
public static void main(String[] args) {
String str1 = new String("abc");
String str2 = new String("abc");
System.out.println(str1.equals(str2));
System.out.println(str1.hashCode());
System.out.println(str2.hashCode());
System.out.println(System.identityHashCode(str1));
System.out.println(System.identityHashCode(str2));
}
}
|
- String클래스는 문자열이 같으면 동일한 해시 코드를 반환하도록 hashCode메서드가 오버라이딩 되어 있다.
- System.identityHashCode은 객체의 주소 값을 해시 코드로 반환하기에 객체 마다 다른 해시 코드가 반환된다.
toString( )
o toString( )메서드는 인스턴스에 대한 정보를 문자열(String)로 제공할 목적으로 정의한 것이다.
o 클래스 작성 시 오버라이딩을 하지 않는 다면 이래와 같이 클래스 이름에 16진수의 해시 코드가 반환된다.
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
|
public class Test {
public static void main(String[] args) {
String str = new String("KOREA");
java.util.Date today = new java.util.Date();
System.out.println(str);
System.out.println(str.toString());
System.out.println(today);
System.out.println(today.toString());
}
}
|
- toString메서드에 대해 String클래스는 인스턴스가 갖고 있는 문자열을 반환하도록, Date클래스는 인스턴스가 갖고 있는 날짜와 시간을 문자열로 변환하여 반환하도록 오버라이딩 되어 있다.
public class Test {
public static void main(String[] args) {
Card c1 = new Card();
Card c2 = new Card();
System.out.println(c1.toString());
System.out.println(c2.toString());
}
}
class Card {
String kind;
int number;
Card(){this("SPACE",1);}
Card(String kind, int number){
this.kind = kind;
this.number = number;
}
@Override
// toString() 오버라이딩
public String toString() {
return "kind : "+kind+", number : "+number;
}
}
|
- toString( )메서드를 오버라이딩 하여 인스턴스가 갖고 있는 변수 값을 문자열로 반환하도록 하였기에 변수의 값이 출력되었다.
- Object클래스에서 toString( )의 접근 제한 범위는 public이기에 오버라이딩 시에도 public으로 해야 한다. (조상의 접근 범위보다 같거나 넓어야 한다.)
'언어 > 자바의 정석' 카테고리의 다른 글
[09-2] clone( ), 얕은 복사(shallow copy), 깊은 복사 - Object클래스 (0) | 2021.02.25 |
---|---|
[08-2] finally, try-with-resources, 사용자정의예외, 예외 던지기 (0) | 2021.02.17 |
[08-1] 예외 처리, try-catch, throw, throws (0) | 2021.02.17 |
[07-8] 내부 클래스(inner class), 익명 클래스(anonymous class) (0) | 2021.02.17 |
[자바의 정석] Chapter 7 객체 지향 프로그래밍II (8) - 인터페이스(interface) (0) | 2021.02.17 |