Ezcho

[java]Object 와 오버라이딩 본문

Java

[java]Object 와 오버라이딩

Ezcho 2022. 9. 28. 21:20

Object클래스란?

모든 클래스의 최상위 클래스: 오브젝트가 가진 메서드는 모든 클래스에서 다 사용할 수 있다.

 

Object클래스의 대표적인 메서드

- 사용자가 알맞게 오버라이딩 해서 사용이 필요함

public class Student {
    String name;
    String number;
    int birthYear;
}

Student 클래스의 선언

 

우리가 알아볼 세가지 메서드에 대한 설명이다.

1. equals: 객체가 가진 값을 비교할 때 사용

(String 클래스의 equals메서드는 object가 가지고 있는 메서드를 오버라이딩 한것이다!)

 

2. toString: 객체가 가지고 있는 값을 문자열로 바꾸어서 리턴한다.

 

3. hashCode: 객체의 해시코드 값을 반환한다.

 

public static void main(String args[]){
    Student s1 = new Student();
    Student s2 = new Student();

    s1.name = "홍길동";
    s1.number = "1234";
    s1.birthYear = 1995;

    s2.name = "홍길동";
    s2.number = "1234";
    s2.birthYear = 1995;

    if(s1.equals(s2))
        System.out.println("They equal");
    else
        System.out.println("Not equlas");

    System.out.println(s1.hashCode());
    System.out.println(s2.hashCode());


}

위의 main함수를 보자. s1과 s2객체를 선언하고 if문과 hashCode를 출력했을 때 그들이 같을까?

 

They equal
901506536
747464370

 

위와 같이 출력된다. 왜 이럴까? 분명 s1과 s2는 동일한 내용을 가지고 있다.

 

이유는 무엇일까? 

equals와 hashCode 메서드는 object가 만든 메서드를 그대로 사용하고 있기 때문이다. 

위의 설명에서 각 메서드는 사용자가 알맞게 오버라이딩 해서 사용해야 할 필요가 있다고 이야기했다.

 

객체의 동등성 비교를 위해 우리는 오버라이드의 필요성을 느꼈는데 어떻게 하면 될까?

 

방법은 단순하다 클래스 내부에 오버라이드 문을 추가해 주면 된다.

 

@Override
public String toString() {
    return "Student{" +
            "name='" + name + '\'' +
            ", number='" + number + '\'' +
            ", birthYear=" + birthYear +
            '}';
}

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    Student student = (Student) o;
    return birthYear == student.birthYear && Objects.equals(name, student.name) && Objects.equals(number, student.number);
}

@Override
public int hashCode() {
    return Objects.hash(name, number, birthYear);
}

이런식으로 구성되어있다.

 

방법은

intelliJ 화면 내에서 우클릭 후 생성 버튼에서 선택 할 수 있다.

 

이런식으로 equals와 hashCode 오버라이드 이후 출력을 비교해보자

 

They equals
545426518
545426518

 

같음을 알 수 있다.

 

조금더 자세히 설명을 하면 

 

Object 클래스 내의 hashCode는 해당 메모리 주소값을 기반으로 생성된 정수값을 반환한다.

그래서 우리가 구현하였던 s1과 s2는 다른 hashCode값을 반환할 수 밖에 없었던 것이다.

public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    Student student = (Student) o;
    return birthYear == student.birthYear && Objects.equals(name, student.name) && Objects.equals(number, student.number);
}

equals 메서드를 먼저 살펴보자. 

객체의 값들을 그냥 비교하는 정도이다. 

 

hashCode를 살펴보자.

public int hashCode() {
    return Objects.hash(name, number, birthYear);
}

hashCode 는 Object클래스의 hash에서 반환된다. name과 number와 birthYear의 String값들에 의한 조합으로 만들어 지는 정수이다.

반환값은 int이다. 근데 int형은 4바이트이다.

 

4,294,967,295

 

반환할 수 있는 최대 int수이다.

하지만 String의 조합은 어떨까  무수히 많다.

위의 수가 상당히 커 보일수 있으나, 우리가 입력할수 있는 String의 최대 크기는 일반적으로 대략 16MB 정도이고 String에서의 char은 2바이트의 크기를 가진다.

 

그래서 결론은 다른 String이지만 중복된 hashCode가 발생할 수 있는것이다.

 

abc와

acb의 hashCode가 같을 수 있는 것이다.

 

그렇기에 우리는 객체의 동등성을 따질 때 equals()메서드를 빼놓을 수 없는것이다.

 

객체의 동등성을 따질 때 우선순위는 먼저

1. hashCode() 가 같아야한다.

2. equals()가 같아야한다.

 

 

'Java' 카테고리의 다른 글

[java] Date, Calendar클래스, Time 패키지  (0) 2022.11.09
[java] java.util패키지  (0) 2022.11.02
[java] Math Class  (0) 2022.10.12
[java] String과 StringBuffer  (0) 2022.10.12
[java] java.lang 패키지  (2) 2022.10.05
Comments