이번 포스팅에서는 Java에서 가장 기본적인 클래스인 Object 클래스에 대해 알아보려 합니다. Java에서 모든 클래스는 기본적으로 Object 클래스를 상속받게 되어 있습니다. 이는 곧, 모든 클래스가 Object 클래스에 정의된 메소드들을 기본적으로 사용할 수 있다는 것을 의미합니다.
이러한 Object 클래스의 메소드 중, toString(), equals(), 그리고 hashCode() 메소드에 초점을 맞춰 알아보도록 하겠습니다.
toString() 메소드
toString() 메소드는 객체를 문자열(String)로 바꿔서 반환해주는 메소드입니다. 이 메소드는 주로 오버라이딩을 통해 인스턴스의 정보를 알기 쉽게 출력하기 위해 사용됩니다.
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
public class Main {
public static void main(String[] args) {
Person person = new Person("홍길동", 25);
System.out.println(person);
}
}
Person{name='홍길동', age=25}
위의 예제에서 Person 클래스는 toString() 메소드를 오버라이딩하여 객체의 정보를 문자열로 쉽게 표현하고 있습니다.
equals() 메소드
equals() 메소드는 두 객체의 주소값을 비교하는 메소드입니다. 주로 오버라이딩을 통해 인스턴스 변수의 값을 비교하도록 사용됩니다.
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Person) {
Person p = (Person) obj;
return this.name.equals(p.name) && this.age == p.age;
} else {
return false;
}
}
}
public class Main {
public static void main(String[] args) {
Person person1 = new Person("홍길동", 25);
Person person2 = new Person("홍길동", 25);
System.out.println("두 사람이 같은 사람인가요? " + person1.equals(person2));
}
}
두 사람이 같은 사람인가요? true
위의 예제에서 Person 클래스는 equals() 메소드를 오버라이딩하여 객체의 이름과 나이가 동일하면 두 객체를 같은 객체로 판단하도록 합니다.
hashCode() 메소드
hashCode() 메소드는 객체의 해시값(주소값과 관련된 어떤 값)을 int로 변환하여 반환합니다. equals()가 오버라이딩되었다면, hashCode()도 함께 오버라이딩되어야 합니다.
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
public class Main {
public static void main(String[] args) {
Person person = new Person("홍길동", 25);
System.out.println("해시코드 : " + person.hashCode());
}
}
해시코드 : [해시코드 결과값]
위의 예제에서 Person 클래스는 hashCode() 메소드를 오버라이딩하여 객체의 이름과 나이가 동일하면 같은 해시코드를 반환하도록 합니다.
equals()와 hashCode()
equals()와 hashCode() 메소드는 상호 의존적인 관계를 가지고 있습니다. 두 메소드는 초기에는 객체의 주소값을 기준으로 작업을 하지만, 개발자가 재정의하여 인스턴스 변수(iv)를 기준으로 작업할 수 있게 합니다. 이렇게 equals() 메소드를 재정의하여 인스턴스 변수를 비교하는 경우, hashCode() 메소드 역시 재정의하여 동일한 인스턴스 변수를 기준으로 해시값을 반환하도록 해야합니다.
이렇게 equals()와 hashCode()를 동시에 재정의하는 이유는 Java의 해시 기반 컬렉션(예: HashSet, HashMap 등)이 객체의 동일성을 판별하는 기준으로 이 두 메소드를 사용하기 때문입니다. 이 컬렉션들은 먼저 객체의 hashCode()를 확인한 후, 해시값이 같을 경우 equals()를 사용하여 실제 동일한 객체인지를 확인합니다. 따라서 equals()의 결과가 true라면 두 객체의 hashCode() 값도 동일해야합니다. 그렇지 않으면 컬렉션의 동작이 예상대로 되지 않을 수 있습니다.
import java.util.Objects;
class Person {
String name;
int age;
Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Person) {
Person p = (Person) obj;
return this.name.equals(p.name) && this.age == p.age;
} else {
return false;
}
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
public class Main {
public static void main(String[] args) {
Person person1 = new Person("홍길동", 25);
Person person2 = new Person("홍길동", 25);
System.out.println("Person1: " + person1);
System.out.println("Person2: " + person2);
System.out.println("두 사람이 같은 사람인가요? " + person1.equals(person2));
System.out.println("Person1의 해시코드: " + person1.hashCode());
System.out.println("Person2의 해시코드: " + person2.hashCode());
}
}
Person1: Person{name='홍길동', age=25}
Person2: Person{name='홍길동', age=25}
두 사람이 같은 사람인가요? true
Person1의 해시코드: [해시코드 결과값]
Person2의 해시코드: [해시코드 결과값]
위의 예제에서는 Person 클래스가 toString(), equals(), hashCode() 메소드를 모두 오버라이딩하고 있습니다. 이를 통해 인스턴스 변수인 '이름'과 '나이'를 기준으로 객체의 정보를 표현하고, 두 객체의 동일성을 판별하며, 같은 정보를 가진 객체에 대한 같은 해시코드를 반환하게 됩니다.
이렇게 Object 클래스의 toString(), equals(), hashCode() 메소드를 재정의함으로써 객체를 더욱 명확하게 표현하고, 객체 간의 동일성을 원하는 기준에 따라 판단하며, 동일한 정보를 가진 객체에 대해 동일한 해시코드를 제공할 수 있게 되었습니다. 이런 방식은 코드의 가독성을 높이고, 데이터를 효율적으로 관리할 수 있게 해줍니다.
'개발 > Java' 카테고리의 다른 글
Java의 StringBuilder/StringBuffer 클래스 (0) | 2023.07.20 |
---|---|
Java의 String 클래스 (0) | 2023.07.20 |
Java에서의 예외처리(Exception Handling) (0) | 2023.07.19 |
Java에서의 함수형 인터페이스와 람다식 (0) | 2023.07.19 |
Java에서의 익명 클래스 (Anonymous Classes) (0) | 2023.07.19 |