equals() 메서드
- 두개의 인스턴스가 같다는 것은 물리적으로 힙 메모리에 저장된 위치가 같다는 것을 의미한다. (주소값 일치)
- == 기호와 equals() 메서드는 두 인스턴스의 주소값을 비교하여 true/false를 반환한다.
- 물리적으로 다르지만 논리적으로 같다고 할 수 있는 경우가 많이 있다. e.g. 같은 학번, 사번, id ...
- equals() 메서드를 재정의해서 두 인스턴스가 논리적으로 동일하다는 조건을 설정할 수 있다.
hashCode() 메서드
- hashCode()는 인스턴스의 저장 주소를 이용해 객체를 식별하는 고유한 정수값인 해쉬 코드를 반환한다.
- 자바에서 JVM은 hash 방식으로 인스턴스를 저장하여 힙 메모리를 관리한다.
- 자료의 특정 값(key 값)에 대한 저장 위치를 반환해주는 hash 함수를 사용한다.
- index = hash(key)
- 두 객체가 논리적으로 같다는 것은 반환하는 해쉬 코드값(value)이 같다는 것 (물리적으로는 다를 수 있음)
equals()와 hashCode()의 관계
- hashCode() 메서드를 실행해서 해쉬 코드 값이 다르면 다른 객체로 판단하고, 같으면 equals() 메서드로 다시 비교한다.
- 만약 hashCode() 메서드만 오버라이딩하고 equals() 메서드는 하지 않는다면 해쉬 값이 일치해도 다른 객체로 판단한다.
- 그럴 경우 원하는 객체를 찾을 수 없다.
- 따라서 두 메서드를 같이 재정의 해주어야 한다.
clone() 메서드
- 객체의 원본을 복제하는데 사용하는 메서드
- 객체의 정보(private으로 선언된 멤버 변수 값 등..)가 동일한 또 다른 인스턴스가 생성되는 것이므로, 객체 지향 프로그램에서 정보 은닉, 객체 보호 관점에서 위배될 수 있다.
- 해당 클래스의 clone() 메서드의 사용을 허용한다는 의미로 복제하고자 하는 객체의 클래스의 implements Cloneable을 명시해주어야 한다.
예제 코드
Student.java
package equalstest;
public class Student {
private int studentId;
private String studentName;
public Student(int studentId, String studentName) {
this.studentId = studentId;
this.studentName = studentName;
}
public String toString() {
return studentId + "," + studentName;
}
}
EqualsTest.java
package equalstest;
public class EqualsTest {
public static void main(String[] args) {
Student std1 = new Student(100, "Lee"); // 논리적으로 동일한 인스턴스 생성
Student std2 = new Student(100, "Lee");
System.out.println(std1 == std2);
System.out.println(std1.equals(std2));
System.out.println(std1.hashCode());
System.out.println(std2.hashCode());
}
}
수행 결과
- 논리적으로는 동일하지만 각 인스턴스는 다른 주소값을 가지므로 '==' 또는 equals() 메서드로 비교했을 때 false를 반환한다.
- Student 클래스의 equals()와 hashCode() 메서드는 재정의되지 않았기 때문에 std1과 std2는 각각 다른 해쉬 코드 값을 가지고, 다른 객체로 판단한다.
- String 클래스의 equals()와 hashCode() 메서드는 재정의되었기 때문에 str1과 str2는 같은 해쉬 코드 값을 갖고, 같은 객체로 판단한다.
false
false
798154996
681842940
true
96354
96354
Equals() 메서드와 hashCode() 메서드 재정의
Student 클래스에 메서드 재정의 부분 추가
@Override
public int hashCode() {
return studentId; // 같으면 동일한 객체로 판단하고자 하는 값을 반환
}
@Override
public boolean equals(Object obj) {
if(obj instanceof Student) {
Student std = (Student)obj;
if(this.studentId == std.studentId) { // 두 객체의 studentId가 같으면 true 반환
return true;
}
}
else {
return false;
}
return false;
}
수행 결과
- equals() 메서드가 재정의되어 논리적으로 같은 객체일 경우 true를 반환한다.
- hashCode() 메서드가 재정의되어 해쉬코드 값으로 studentId를 반환한다.
- 만약 equals() 메서드를 오버라이딩 해주지 않는다면 std1과 std2는 같은 해쉬 코드 값을 가져도 다른 객체로 판단한다.
false
true
100
100
clone() 메서드 활용해서 인스턴스 복제하기
Student 클래스에 implements Cloneable 명시해주고 clone() 메서드 재정의 부분 추가
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
EqualsTest 클래스에 clone() 메서드로 std1 복제하기
- clone() 메서드를 사용하기 위해서는 throws declaration을 해주어야 함
- clone()은 Object의 인스턴스를 생성해주기 때문에 Student 형으로 다운캐스팅 해주어야 한다.
std1.setStudentName("Kim");
Student copyStudent = (Student)std1.clone();
System.out.println(copyStudent);
수행 결과
100,Kim'Java' 카테고리의 다른 글
| [Java 클래스] 자바의 문자열 관련 클래스 (0) | 2022.02.03 |
|---|---|
| [Java 클래스] Object 클래스 (0) | 2022.02.02 |
| [Java 객체지향] 인터페이스 구현 예제 프로그램 (상담원 연결 구현) (0) | 2022.02.02 |