eterno

[JAVA] Object 클래스(toString(), equals(), hashCode(), clone() ) 본문

JAVA

[JAVA] Object 클래스(toString(), equals(), hashCode(), clone() )

영원한별똥별 2023. 2. 7. 11:28
728x90
반응형

java.lang 패키지 안에는 기본적으로 많이 사용하는 클래스들이 포함되어 있습니다.

그 중 모든 클래스의 최상위 클래스는 Object 클래스입니다.

즉, 모든 클래스는 java.lang.Object 클래스에 있는 메서드를 재정의 하여 사용할 수 있다는 것 입니다.

 

Object 클래스 메서드

Object에는 1개의 생성자11개의 함수로 구성되어있습니다.

 

[생성자]

Object public Object()

[메서드]

반환형 메서드
protected Object clone()
boolean equals(Object obj)
protected void finalize()
Class<?> getClass()
int hashCode()
void notify()
void notifyAll()
String toString()
void wait()
void wait(long timeout)
void wait(long timeout, int nanos)

Object에 있는 메서드를 재정의 하여 사용할 수 있습니다.

 

단, final 로 선언되어 있다면 재정의 불가능합니다.

(* final은 변수를 상수화 시키겠다는 예약어)

Object클래스에서 자주 사용하는 메서드는

toString(), equals(), hashCode(), clone() 입니다.

 

 

toString()
: 개체의 문자열 표현을 반환
package object;

class Book{

	int bookNumber;
	String bookName;
	
	public Book(int bookNumber, String bookName) {
		this.bookNumber = bookNumber;
		this.bookName = bookName;
	}

}

public class ToString {

	public static void main(String[] args) {
		
		Book book = new Book(100, "국어책");

		System.out.println(book); //결과값 : object.Book@3d4eac69
		System.out.println(book.toString()); //결과값 : object.Book@3d4eac69
	}
}

toString()의 원형은 "클래스이름. 함수이름. hashcode.주소값" 입니다.

문자열로 반환하기 위해서는 Object클래스의 toString() 메서드를 재정의 해야합니다.

 

마우스 오른쪽버튼 클릭해서 Source -> Override/Implement Methods... 클릭 하면

재정의 할 수 있는 메서드가 보이는데 Object클래스에서 재정의 가능한 메서드 중 toString() 클릭하면 됩니다.

Source -> Generate toString()... 이 메뉴로 사용해도 됩니다.

 

@Override
	public String toString() {
		
		return bookNumber +", "+ bookName;
	}

재정의하여 실행하면

문자열로 출력되는 것을 확인할 수 있습니다.

 

 

equals(Object obj)
: 다른 개체가 이 개체와 "동일한지" 확인

package object;

class Animal{
	
	String dog;
	String cat;
	
	public Animal(String dog, String cat) {
		this.dog = dog;
		this.cat = cat;
	}

	@Override
	public boolean equals(Object obj) {
		
		if(obj instanceof Animal) {
			Animal std = (Animal)obj;
			if(this.dog == std.dog) return true;
			else return false;
		}
		return false;
	}
}

public class EqualsTest {
	public static void main(String[] args) {
		
		Animal st1 = new Animal("멍멍이","냐옹이");
		Animal st2 = new Animal("멍멍이","냐옹이");
		
		System.out.println(st1 == st2); //결과값 : false
		System.out.println(st1.equals(st2)); //결과값 : true
	}
}

== 는 주소값이 일치한지 확인하기 떄문에 인스턴스의 주소가 달라 false를 반환하고

Object.equals()메서드는 인스턴스가 같은지 확인하기때문에 true를 반환합니다.

 

.equals()메서드도 toString과 동일하게 재정의 하여 사용해야 합니다.

equals()메서드의 매개변수는 Object형이기때문에 다운캐스팅하여 값을 비교해주어야 합니다.

	@Override
	public boolean equals(Object obj) {
		
		if(obj instanceof Animal) { // obj의 자료형이 Animal인지 확인하는 if문
			Animal std = (Animal)obj; // 맞다면 obj를 Animal로 형변환(다운캐스팅)
			if(this.dog == std.dog) return true; //입력한 변수값과 다운캐스팅한 변수값이 같다면 true반환
			else return false; //아니라면 false반환
		}
		return false;
	}

 

 

hashCode()
: 개체의 해시 코드 값을 반환

toString()메서드의 구조는 getClass().getName() + '@' + Integer.toHexString(hashCode()) 입니다.
여기서 사용되는 hashCode() 는 주소값을 반환하는 메서드 이고 

반환값이 정수형(int)이여서 객체의 주소값을 10진수로 반환합니다.

 

package object;

class Food{
	
	int foodCode;
	String food;
	
	public Food(int foodCode, String food) {
		this.foodCode = foodCode;
		this.food = food;
	}

	@Override
	public int hashCode() {
		return foodCode;
	}
}

public class HashCodeEx {
	
	public static void main(String[] args) {
		Food food1 = new Food(1000, "사과");
		Food food2 = new Food(1000, "사과");
		
		System.out.println(food1.hashCode()); //결과값(오버라이딩전) :  1028566121 , 결과값(오버라이딩후) : 1000  
		System.out.println(food2.hashCode()); //결과값(오버라이딩전) :  1118140819 , 결과값(오버라이딩후) : 1000  

		System.out.println(System.identityHashCode(food1)); //결과값 : 1028566121
		System.out.println(System.identityHashCode(food2)); //결과값 : 1118140819

}
}

* 실제 주소값을 반환하려면 System.identityHashCode() 를 사용하면 됩니다.

 

 

clone()
: 이 개체의 복사본을 만들고 반환

개체의 원본을 유지하고 틀만 복사본을 만드는 것.

메모리 주소가 다른 인스턴스가 생성됩니다.

clone() 메서드를 사용할 때 발생할 수 있는 오류를 예외처리해주어야 합니다.

=> throws CloneNotSupportedException 

 

clone()메서드를 사용하는 클래스 에 Cloneable 인스턴스를 선언하여 복제를 허용해주어야 합니다.

* Cloneable 를 선언하지 않으면 Exception in thread "main" java.lang.CloneNotSupportedException: object.Circle 오류발생

package object;

class Point{
	int x;
	int y;
	
	public Point(int x, int y) {
		this.x = x;
		this.y = y;
	}

	@Override
	public String toString() {
		return "Point [x=" + x + ", y=" + y + "]";
	}
}

class Circle implements Cloneable{
	
	Point point;
	int radius;
	
	public Circle(int x, int y, int radius) {
		this.radius = radius;
		point = new Point(x, y);
	}

	@Override
	public String toString() {
		return "Circle [point=" + point + ", radius=" + radius + "]";
	}

	@Override
	protected Object clone() throws CloneNotSupportedException { // 예외처리
		return super.clone();
	}
}

public class ObjectCloneTest {

	public static void main(String[] args) throws CloneNotSupportedException {
			
		Circle c1 = new Circle(5, 10, 2);
		Circle c1_1 = (Circle) c1.clone(); //clone()의 데이터 형이 Object여서 다운캐스팅
		
		System.out.println(c1);
		System.out.println(c1_1);
	}
}

 

** java.lang.String, java.lang.Integer 등등 lang에 있는 클래스는

Object 메서드가 재정의 되어있어서 Override 하지 않아도 되지만 그 외의 클래스는 재정의 하여 사용해야 합니다.

 

 

 

 

자세한 사항은 java api에서 확인가능합니다.

https://docs.oracle.com/javase/8/docs/api/index.html

 

Java Platform SE 8

 

docs.oracle.com

 

참고문헌) DoIt! 자바프로그래밍입문

728x90
반응형