Object클래스와 equals()
Object 클래스
- 모든 클래스의 최고 조상. 오직 11개의 메서드만을 가지고 있다.
- notify(), wait() 등은 쓰레드와 관련된 메서드이다.
이중에, notifiy()와 wait()는 쓰레드 하고 관련된 메서드다.
13장에서 공부할 것이므로 그 전까지는 그렇구나 정도만 알고 넘어가자.
나머지 다른 메서드들 중에서, equals, toString정도는 우리가 이미 사용해봤다.
그것들을 제외한 나머지 중에, finalize는 거의 사용하지 않는다.
finalize는 생성자와 반대되는 개념인데, 객체가 소멸될 때 가비지 컬렉터에 의해 자동 호출되는 메서드다.
생성자가 하는 일은 객체 초기화인데, finalize는 객체를 제거하기 전에 마무리 작업을 여기에 넣어주라고 만든 메서드인데,
메모리가 부족할 때, 가비지 컬렉터가 빨리 객체를 없애야 하는데, 이 fnalize에 어떤 코드를 넣어 놓으면, 당장 메모리가 없어서 프로그램이 죽게생겼는데, 이 finalize에 있는 코드를 실행하느라고 메모리를 정리하는데에 시간이 많이 걸리게 되는 문제가 생길 수 있다.
그래서 왠만하면 사용하지 말라고 권장한다. 실제로도 거의 사용을 안한다고 한다.
clone은 객체를 복사할 때 사용한다.
equals는 객체 비교에 사용한다.
toString도 객체를 문자열로 바꿔서 반환할 때 사용한다.
hashCode는 객체의 해시코드를 반환한다.
getClass는 객체의 클래스 정보를 반환한다. (설계도 정보)
클래스 중에 첫글자가 대문자인 클래스가 있는데, 이것은 뭐냐면, 클래스 정보를 담기위한 클래스이다.
자바 소스를 컴파일 하면 *.class 파일이 나오는데,
예를 들어 Hello.java를 컴파일하면 Hello.class파일이 생기는데,
이 클래스 파일이 메모리에 올라갈 때, Hello라는 클래스의 class객체가 자동으로 만들어진다.
이것이 Hello라는 클래스를 위한 클래스 객체인데, 이객체에는 Hello클래스에 대한정보가 다 담겨있다. (조상이 누구고, IV가 몇개고, 메서드가 몇개있고, 생성자가 뭐가있고 등의 모든 정보가 담겨있다.)
즉, 설계도 객체인 것이다.
그래서 어떤 객체에 대해서 getClass를 호출하면, 설계도 객체를 준다.
이 설계도 객체를 통해서 뭘 할 수 있냐면,
1. 객체 생성 하기
2. 객체 정보 얻기
등을 할 수 있다.
그러니까, Hello.class파일에 있는 내용들을 사용하기 쉽게 정리해서 저장하 놓았다고 생각하면 된다.
이 설계도를 가지고 객체 생성도 하고, 객체 정보도 얻을 수 있게 해둔 것을 ReflectionAPI라고 한다. (자바에 기본포함)
이 관련 클래스들을 이용하면, 우리가 할 수 있는 훨씬 많아진다.
그리고, 위의 표에서 메서드에서 protected로 되어 있는 것들은
오버라이딩을 해서 public으로 변경해야 사용가능하다.(내용도 오버라이딩해야함)
표에있는 메서드들은 대부분 오버라이딩을 해야한다. 필수는 아니지만 오버라이딩 하는 경우가 많다.
기본적인 구현을 우리가 작성한 클래스에 맞게 내용을 조금 변경해야 하기 때문이다.
equals (Object obj)
- 객체 자신(this)과 주어진 객체(obj)를 비교한다. 같으면 true, 다르면 false.
- Object클래스의 equals()는 객체의 주소를 비교 (참조변수 값 비교)
equals의 반환 타입은 boolean이다.
Object클래스의 equals()는 주소를 비교하게 되어있다.
객체 자신과 Obj의 주소가 같을 떄만 true다.
Value라는 클래스가 있을 떄, Value는 iv를 하나 가지고 있다.
value객체 2개를 만들고, equals로 비교한 결과를 println으로 출력하면 결과가 어떻게 나올까?
v1과v2는 서로 다른 객체다. 그래서 주소가 다르다. 같은 주소의 객체가 2개 존재할 수 없다.
따라서 서로 다른 두 객체는 항상 주소가 다르다.
좌측 코드 Value에서 오버라이딩을 하지 않았으므로 조상인 Object의 toSrtring을 그대로 쓴다.
그래서 this값(v1)이 0x1234, obj(v2)의 값이 0x2345이다.
따라서 주소 비교를 하면 false가 나온다.
만약에, 객체에 저장된 iv값을 비교하도록 하려면 어떻게 해야할까?
eqauls()를 오버라이딩 해야할 것이다.
그래야 V1과 V2로 equals로 비교한 결과가 true가 나올 것이다.
equals(Object obj)의 오버라이딩
- 인스턴스 변수(iv)의 값을 비교하도록 equals()를 오버라이딩해야 한다.
앞서 살펴본 것처럼, Object클래스의 equals는 객체의 주소를 비교하게 되어있기 때문에,
대부분의 경우 인스턴스 변수(iv)값을 비교하도록 equals()를 오버라이딩 한다.
객체가 다르다는 것은, iv값이 다르다는 것이다.
cv는 객체마다 공통인 것이고, iv값은 객체마다 다르다.
그래서 cv는 객체마다 같아서 구별이 안되서 객체는 iv를 가지고 비교한다.
만약, 모든 iv가 같다면, 그 두 객체는 같다고 보는 것이다.
그래서 Iv값을 가지고 비교하도록 equals()를 오버라이딩 한다.
오버라이딩 할 때는, 형변환을 해야한다.
예제 Person클래스가 있는데,
사람은 사람마다 id(주민번호)를 가지고 있다.
그래서 equalsㄹㄹ 어떻게 오버라이딩 했냐면,
id값을 가지고 비교하도록 오버라이딩 했다.
그래서 person객체를 두개 만들었을 때, 서로 다른 객체라서 두 객체는 주소가 다르지만, id는 같다.
비교연산자로 두 객체의 주소를 비교하면 false지만,
오버라이딩한 equals로 두 객체의 iv(id)를 비교하면 true다.
'JAVA' 카테고리의 다른 글
String클래스, 문자열 비교, 빈 문자열 (0) | 2022.04.14 |
---|---|
hashCode(), toString() (0) | 2022.04.14 |
연결된 예외 (0) | 2022.04.12 |
사용자 정의 예외 만들기, 예외 던지기 (0) | 2022.04.12 |
예외 선언하기, finally블럭 (0) | 2022.04.11 |
댓글
이 글 공유하기
다른 글
-
String클래스, 문자열 비교, 빈 문자열
String클래스, 문자열 비교, 빈 문자열
2022.04.14 -
hashCode(), toString()
hashCode(), toString()
2022.04.14 -
연결된 예외
연결된 예외
2022.04.12 -
사용자 정의 예외 만들기, 예외 던지기
사용자 정의 예외 만들기, 예외 던지기
2022.04.12