본문 바로가기
Java

[Java] Obect 클래스 / toString() / equals() / hashCode()

by bkuk 2022. 10. 3.

java.lang 패키지

자바를 통해 프로그램을 구현하면서, String 이나 Integer와 같은 클래스를 사용했습니다.

String 클래스의 전체 이름은 java.lang.String이며, Integer  클래스의 전체 이름은 java.lang.Integer입니다.

String, Integer와 같이 외부 패키지에서 선언한 클래스를 사용할 때는

import문으로 클래스가 어느 패키지에 속해 있는 선언해야 합니다.

String  또는 Integer 클래스 같은 경우 컴파일 할때 import.java.lang.* 문장이 자동 추가되어

java.lang 패키지의 모든 하위 클래스를 참조가 가능하게 되며, 컴파일 에러가 발생하지 않습니다.

 

java.lang.Object

 

object 클래스는 모든 자바 클래스의 최상위 클래스 입니다. 모든 클래스는 object 클래스로부터 상속을 받습니다.

왼쪽과 같이 코드를 작성하면 오른쪽과 같이 extends object가 자동으로 쓰입니다.

'아래 사진은 Object 클래가 String 클래스보다 상위 클래스다' 라고 표현하기 위한 사진입니다.


 

toString() 메서드

Object 클래스에서 기본적으로 제공하는 toString() 메서드객체 정보를 문자열(String)로 변환해줍니다.

Object 클래스를 상속받은 모든 클래스는 toString()을 재정의할 수 있습니다.

toString() 메서드의 원형은 생성된 인스턴스의 클래스 이름과 주소 값을 보여 줍니다.

System.out.println() 출력문 참조 변수를 기입하면 인스턴스 정보가 출력되는데, 

이떄 자동으로 호출되는 메서드toString()입니다.

Object 클래스의 메서드인 toString() 메서드 원형은 아래와 같습니다.

getClass().getName() + '@' + Integer.toHexString( hashCode() )

 

해석을 해보면 '클래스 이름@ 해시 코드' 입니다. 

 

Account 클래스에서 toString() 메서드를 재정의하기

 

위에서 정의했던 Account 클래스의 참조 변수를 사용해서,

계좌번호(Account Number)와 이름(Name)을 출력해 보겠습니다.


equals() 메서드

equals() 메서드는 두 인스턴스의 주소 값을 비교하여 boolean 값(true/false)을 반환해 줍니다.

주소 값이 같다면 당연히 같은 인스턴스입니다만, 

서로 다른 주소 값을 가질 떄도 같은 인스턴스라고 정의할 수 있는 경우가 있습니다.

물리적 동일성(인스턴스의 메모리 주소가 같음)뿐 아니라

논리적 동일성(논리적으로 두 인스턴스가 같음)을 구현할 때도 equals() 메서드를 재정의 후 사용합니다.

 

'두 인스턴스가 물리적으로 같다'

'두 인스턴스가 물리적으로 같다'라는 것은 주소 값이 같은 경우를 말합니다. 

두 변수가 같은 메모리 주소를 가르키고 있다는 뜻입니다.

 

위 사진을 보면 ac1, ac2가 가르키는 인스턴스ac3이 가르키는 인스턴스는 서로 다른 주소를 가르키고 있지만,

저장된 정보는 같습니다.


논리적으로는 ac1, ac2, ac3을 같은 정보로 처리하는 것이 맞다고 가정한다면?

 

추가적인 설명을 위해

a1, a2, a3를 각각 == 기호로 비교하고, equals() 메서드로 비교해보겠습니다.

 

equals() 메서드의 원래 기능은 두 인스턴의 주소를 비교하는 것이므로,

a1와 a3의 equlas() 비교에서는 false를 반환합니다.

 

만약, 계좌번호가 같고 이름이 같은 상황이 발생했을 때의 이를 처리하는 방식을 두가지로 나눠본다면?

==는 단순히 물리적으로 같은 메모리 주소인지 여부를 확인할 수 있고,

Object의 equals() 메서드는 override하여 논리적으로 같은 인스턴스인지(메모리 주소가 다르더라도, 같은 사람인지) 확인하도록 구현하도록 해보겠습니다.

 

	public boolean equals(Object obj) {
		if( obj instanceof Account) {
			
			Account ac = (Account) obj;
			if(this.accountNumber == ac.accountNumber)
				return true;
			else return false;
		
		} return false;
	}

equals() 메서드의 매개변수는 Object형입니다.

비교될 객체가 Object형 매개변수로 전달되면 instanceof를 사용하여

매개변수의 원래 자료형이 Account인지 확인합니다.

this의 계좌번호와 매개변수로 전달된 객체의 계좌번호가 같으면 true를 반환합니다.

 


hashCode() 메서드

해시(hash)는 정보를 저장하거나 검색할 때 사용하는 구조입니다.

정보를 어디에 저장할 것인지, 어디서 가져올 것인지 해시 함수를 사용하여 구현합니다.

해시 함수는 객체의 특징 정보(키 값)를 매개변수 값으로 넣으면

그 객체가 저장되어야 할 위치나 저장된 해시 테이블 주소(위치)를 반환합니다. 

따라서 객체 정보를 알면 해당 객체의 위치를 빠르게 검색할 수 있습니다.

 

Account 클래스에서 hashCOde() 메서드 재정의

앞에서 서로 다른 인스턴스로 생성된 두 학생이 주소 값이 다르더라도

논리적으로 같은 학생이라면 ture를 반환해주는 equals() 메서드를 재정의 해봤습니다.

위와 동일하게 논리적으로 동일한 두 학생은 같은 해시 코드 값을 반환하도록

hashCode() 메서드도 재정의 해보겠습니다.

 

댓글