[JAVA-3] Object 탐구하기

극락코딩·2021년 8월 6일
0

java

목록 보기
3/4
post-thumbnail

Object(객체) 탐구하기 - toString(), equals(), hashCode()


😱 이번에는?

  • Object(객체) 탐구하기 - toString(), equals(), hashCode() 언제 쓰이는지!!

🛒 들어가면서

  • 프로젝트를 진행하다보면, 항상 toString(), equals(), hashCode()를 어떻게 재정의할지 고민합니다..
  • 그러다 보니까 Lombok에서 지원하는 @EqualsAndHashCode @ToString을 사용하는 것 같습니다..ㅜㅜ
  • 이펙티브 자바와 클린코드 책을 읽으면서, 어노테이션을 최소화하고, 개발자가 직접 작성하는 방향이 좋다고 배우게 된 것 같습니다.
    • 필요없는 코드가 자동 생성되는 것을 방지하기 위해서 라고 학습했습니다!
  • 무엇이 좋은지, 그리고 @Override를 어떻게 해야될지 고민했던 것 같습니다,,
  • 이번 기회에 Object Class에 있는 method를 어떻게 사용할지에 대해 작성하도록 하겠습니당!!!~~

😆 Object Class란?

  • 자바 클래스의 최최최고 조상 클래스입니다!!!

    모든 클래스는 Object 클래스를 상속받고 있습니다!
    우리가 따로 extends하지 않더라도 기본으로 상속을 제공합니다!!

  • java.lang pakage에 속하며, 자바의 가장 기본적인 동작들을 수행합니다!

    그렇기 때문에 별다른 import 없이 사용 가능해요~~

🖊 toString()

  • toString은 기본적으로 해당 인스턴스의 대한 정보를 문자열로 반환합니다!

    기본적으로 toString을 쓰게 되면! 아래와 같이 참조된 정보를 출력하게 됩니다!!
    사용자가 원하는 값을 출력하기 위해서는 재정의가 필요합니다!

DongGeon dongGeon = new DongGeon();
System.out.println(dongGeon);
    
>> DongGeon@1233123C
  • Lombok을 이용하게 되면서 toString을 조금 더 편하게 사용할 수 있습니다!

    Lombok을 사용하면, 정말 편리하게 toString을 이용할 수 있지만! 모든 데이터가 같이 출력되기 때문에 필요 없는 데이터도 같이 출력되게 됩니다 ㅜㅜ

@ToString
public Class DongGeon {
	private int age;
    private String name;
    
    public DongGeon(int age, String name){
    	this.age = age;
        this.name = name;
    }
}

DongGeon dongGeon = new DongGeon(25, "김동건");
System.out.println(dongGeon);

>> DongGeon(age=25, name=김동건)
  • toString을 재정의 하는 이유!
  1. 객체가 가진 정보를 조금 더 가독성 있게 보이기 위하여!
  2. 개발자가 원하는 정보를 출력하도록 변경할 필요가 있다!!
public Class DongGeon {
	private int age;
    private String name;
    
    public DongGeon(int age, String name){
    	this.age = age;
        this.name = name;
    }
    
    @Override
    public String toString() {
    	return "나는 " + name + "이고, 나이는 " + age + "이다";
    }
}

DongGeon dongGeon = new DongGeon(25, "김동건");
System.out.println(dongGeon);

>> 나는 동건이고, 나이는 25이다

🥳 equals()

각 인스턴스가 동일한 인스턴스인지 비교합니다! 내용이 같은지, 주소가 같은지 확인할 수 있지만, == 대신 equals를 쓰는 이유는 재정의가 가능하기 때문입니다! 그리고 참조형 필드를 비교하기 위해서도요!

  • 동일성과 동등성

    비슷하겠지만, 동일성은 오브젝트가 완전히 같은지를 의미합니다
    동등성은 같은 정보를 내포가 있는지를 의미합니다!!

DongGeon donggeon1 = new DongGeon(25, "김동건");
DongGeon donggeon2 = new DongGeon(25, "김동건");

boolean checkOne = donggeon1 == donggeon2;
boolean checkTwo = donggeon1.equals(donggeon2);
  • == 연산을 사용할 경우 원시타입의 경우에는 값을 비교합니다! 정황상 donggeon1과 donggeon2는 같은 값을 가지고 있지만!!서로 다른 주소이기 때문에 false가 리턴되게 됩니다 ㅜㅠㅜ

  • 반대로 equals연산을 사용하게 되면 재정의하여 equals가 가진 기본 성능을 바꿀 수 있다!
    + Object Class를 까보면, equals는 기본적으로 == 연산을 하고 있다!

    public boolean equals(Object obj) {
        return (this == obj);
    }
  • 기본으로 제공되는 equals 연산자는 결국 ==와 같은 기능을 제공한댜.... 그렇기 때문에 @Override를 통해 우리의 코드에 맞는 equals를 재정의해야 합니당!
 @Override
    public boolean equals(Object object) {
        if (!(object instanceof this)) {
            return false;
        }
        return this.equals(object);
    }
  • 위의 코드처럼 instanceof 연산자를 통해 재정의하면 더욱 equals의 기능을 극대화시킬 수 있다!

😩 hashCode()

hashCode는 객체를 식별할 수 있는 정수 값을 의미합니다! hashCode를 통해 저장된 데이터를 더 빠르게 조회할 수 있습니다!

  • hashCode()는 원래 사용자가 직접 재정의해줘서 구해줘야 합니다!! ㅜㅜ
    하지만 각 IDE가 재정의해주는 hashCode가 정말 좋게 구현되어 있기 때문에 이점은 PASS~

  • hashCode를 재정의함으로써 HashTable에 HashCode가 최적화되어 삽입될 수 있는 장점이 있습니다!
    + 하지만, ,.,, hashCode를 재정의하면서 나오는 불편함...크름...

    @Override
    public int hashCode() {
        if (this == null) {
            return 0;
        }
        return this.hashCode();
    }
  • 저의 경우에도 hashCode를 직접 재정의해서 구하기 보다는 IDE 또는 LOMBOK에서 만들어주는 hashCode를 사용하고 있습니다!

🎲 결론

toString(), hashCode(), toString() 모두 재정의하여 개발자가 원하는 값을 반환하도록, 혹은 내부 로직을 변경함으로써 원하는 기능을 제공하도록 수정하는 것이 좋다고 생각합니다!

다만!! 우리에게는 LOMBOK이 있고 편리한 TOOL이 너무나 많습니다 ㅜㅜ

모든 것을 재정의하고 모든 부분에서 어노테이션 없이 사용하기에는 아직 초보(예비)개발자가 하기에 너무나 > 큰 부담이 되는 것 같습니다..ㅜㅜㅜ

그렇기 때문에, 일단 어노테이션을 작성해서 개발을 하다가, 리펙토링을 하며, 하나씩 어노테이션을 지우고 직접 구현해 나가는 방향도 저는 좋다고 생각합니다... 물론 지극히 개인적인 의견입니다!!

profile
한 줄에 의미를, 한 줄에 고민을

0개의 댓글