본문 바로가기
JAVA

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

by nam_ji 2024. 2. 14.

Object (equals, toString, hashCode) 클래스

Class Object

  • java.lang 패키지 중에서도 가장 많이 사용되는 클래스로, 모든 자바 클래스의 최고 조상 클래스입니다.
  • 다라서 자바의 모든 클래스는 Object 클래스의 모든 메서드를 바로 사용할 수 있는데, Object는 총 11개의 메서드로 구성되어 있습니다.
    • java.lang 패키지는 자바에서 가장 기본적인 동작을 수행하는 클래스들의 집합입니다.
    • java.lang 패키지의 클래스들은 import문을 사용하지 않아도 클래스 이름만으로 바로 사용할 수 있도록 하고 있습니다.
    • java.lang 상속 클래스 : String, StringBuilder, Boolean, Character, Number(Byte, Short, Integer, Long, Float, Double)

1. Object Method toString()

  • toString() 메서드는 해당 인스턴스에 대한 정보를 문자열로 반환하는 메서드입니다. 이때 반환되는 문자열은 클래스 이름과 함께 구분자로 '@'가 사용되며, 그 뒤로 16진수 해시 코드 (hash code)가 추가됩니다.
  • 16진수 해시 코드 값은 인스턴스의 주소를 가리키는 값으로, 인스턴스마다 모두 다르게 반환됩니다.
  • 자바에서 toString() 메서드는 기본적으로 각 API 클래스마다 자체적으로 오버라이딩을 통해 재정의 되어 있습니다.
    마찬가지로, 개발자는자신이 만든 클래스에 대하여 toString 메서드를 재정의 하여 사용할 수 있습니다.
    • 더보기
      import java.util.Arrays;
      
      public class ObjectTest {
        // toString()
        public static void main(String[] args) {
          ObjectTest objectTest = new ObjectTest();
      
          objectTest.toStringRun();
          objectTest.toStringOverriding();
      
        }
      
        private void toStringRun() {
          String myName = "namji";
          System.out.println("myName = " + myName);
          // 컴파일 경고 발생
          // this object (which is already a string!) is itself returned.
          System.out.println("myName = " + myName.toString());
          /**
           * 출력 :
           * myName = namji
           * myName = namji
           */
      
          int[] intArr = new int[]{1,2,3,4,5};
          System.out.println("intArr = " + intArr);
          System.out.println("intArr = " + Arrays.toString(intArr));
          /**
           * 출력 :
           * intArr = [I@23fc625e
           * intArr = [1, 2, 3, 4, 5]
           */
        }
      
        private void toStringOverriding() {
          // onlineClass 객체 생성
          OnlineClass onlineClass1 = new OnlineClass(1, "SpringBoot", true);
          OnlineClass onlineClass2 = new OnlineClass(2, "SpringFrameWork", true);
      
          // class toString 메서드 호출
          // .toString() 하지 않아도 println 메서드가 String으로 변환하여 출력하기 때문에 결과는 동일합니다.
          System.out.println("onlineClass1.toString() = " + onlineClass1.toString());
          System.out.println("onlineClass1 = " + onlineClass1);
          System.out.println("onlineClass2 = " + onlineClass2);
      
          /**
           * 출력 :
           * onlineClass1.toString() = ObjectTest$OnlineClass@4f023edb
           * onlineClass1 = ObjectTest$OnlineClass@4f023edb
           * onlineClass2 = ObjectTest$OnlineClass@3a71f4dd
           */
        }
      
        static class OnlineClass {
      
          public int getId() {
            return id;
          }
      
          public String getTitle() {
            return title;
          }
      
          public boolean isCloesd() {
            return cloesd;
          }
      
          public void setId(int id) {
            this.id = id;
          }
      
          public void setTitle(String title) {
            this.title = title;
          }
      
          public void setCloesd(boolean cloesd) {
            this.cloesd = cloesd;
          }
      
          public OnlineClass(int id, String title, boolean cloesd) {
            this.id = id;
            this.title = title;
            this.cloesd = cloesd;
          }
      
          private int id;
          private String title;
          private boolean cloesd;
        }
      }
  • Java API Class
    • API (Allication Programming Interface), 개발에 자주 사용되는 클래스나 인터페이스와 모음으로 System.String 클래스 등도 모두 API에 속합니다. 
      설치 경로 : "jdk설치 폴더 jre/lib/rt.jar" 폴더 안에 class 형태로 저장되어 있음을 확인 가능합니다.
    • Object, String, StringBuilder, Math, Wrapper, Enum, Arrays, Calendar
  • toString() 오버라이딩
    • @Override 어노테이션으로 Object 클래스의 toString 메서드를 재정의 할 수 있습니다.
    • Lombok의 @ToString 어노테이션을 통하여 재정의를 편하게 할 수 있습니다.
      • 더보기
        public class ObjectTests {
        
            public static void main(String[] args) {
                ObjectTests objectTests = new ObjectTests();
        
                objectTests.toStringOverriding();
        
            }
        
            private void toStringOverriding() {
                // OnlineClass 객체 생성
                OnlineClass class1 = new OnlineClass(1, "spring boot", true);
                OnlineClass class2 = new OnlineClass(2, "spring data jpa", true);
        
                // Class toString 메소드 호출
                System.out.println("class1 = " + class1.toString());
                System.out.println("class1 = " + class1);
                System.out.println("class2 = " + class2);
        
                /**
                 * 출력1 기본 toString()
                 * class1 = com.study.java8.object.ObjectTests$OnlineClass@df9f5f
                 * class1 = com.study.java8.object.ObjectTests$OnlineClass@df9f5f
                 * class2 = com.study.java8.object.ObjectTests$OnlineClass@5ede7b
                 */
        
                /**
                 * 출력2 사용자 재정의 toString()
                 * class1 = com.study.java8.object.ObjectTests$OnlineClass@71f4dd@ id: 1, title: spring boot
                 * class1 = com.study.java8.object.ObjectTests$OnlineClass@71f4dd@ id: 1, title: spring boot
                 * class2 = com.study.java8.object.ObjectTests$OnlineClass@df9f5f@ id: 2, title: spring data jpa
                 */
        
                /**
                 * 출력3 Lombok 제공 toString()
                 * class1 = ObjectTests.OnlineClass(id=1, title=spring boot, closed=true)
                 * class1 = ObjectTests.OnlineClass(id=1, title=spring boot, closed=true)
                 * class2 = ObjectTests.OnlineClass(id=2, title=spring data jpa, closed=true)
                 */
            }
        
            @Getter @Setter
            @AllArgsConstructor
            @ToString
            static class OnlineClass {
        
                private int id;
                private String title;
                private boolean closed;
        
                /*
                @Override
                public String toString() {
                    return super.toString() + "@ id: " + id + ", title: " + title;
                }
                */
            }
        }

2. Object Method equals()

  • equals() 메서드는 해당 인스턴스를 매개변수로 전달받는 참조 변수와 비교하여, 그 결과를 반환하는 메서드입니다.
    이때 참조 변수가 가리키는 값을 비교하므로, 서로 다른 두 객체는 언제나 false를 반환합니다.
  • equals() 메서드도 마찬가지로 기본적으로 각 API 클래스마다 자체적으로 오버라이딩을 통해 재정의 되어 있습니다.
  • equals()는 사용자가 어떻게 재정의 하느냐에 따라서 원하는 기준으로 비교가 가능합니다.
    • equals()와 항등 연산자(==)의 차이점
      • ==
        • 참조 비교 (Reference Comparison)로, 두 객체가 같은 메모리 공간을 가리키는지 확인합니다.
          = 객체의 동일성
        • 모든 기본 유형 (Primitive Types)에 대해서는 값을 비교하는 것으로 보이는데, Primitive 역시 Content Pool에 있는 특정 상수를 참조하는 것이기 때문에 결국 주소 값을 비교하는 것으로 볼 수 있습니다.
      • equals()
        • 객체 내용 비교 (Content Comparison) 메서드로, 두 객체의 값이 같은지 확인합니다. 즉, 문자열의 데이터 / 내용을 기반으로 바교합니다.
          = 논리적 동일성 Primitive Types에는 적용이 불가능합니다.
  • 더보기
    import java.lang.annotation.Retention;
    import java.lang.reflect.Member;
    import java.util.Arrays;
    import java.util.Objects;
    import jdk.jshell.Snippet.Status;
    
    public class ObjectTest {
      // toString()
      public static void main(String[] args) {
        ObjectTest objectTest = new ObjectTest();
    
        objectTest.equalsRun();
    
      }
      
      private void equalsRun() {
        Member member1 = new Member("namji");
        Member member2 = new Member("namji");
    
        System.out.println("member1 = " + member1);
        System.out.println("member2 = " + member2);
        System.out.println("member1 == member2 = " + (member1 == member2));
        System.out.println("member1.equals(member2) = " + member1.equals(member2));
    
        /**
         * 출력1 : 기본 equals()
         * member1 = com.study.java8.object.ObjectTests$Member@71f4dd@name: namji
         * member2 = com.study.java8.object.ObjectTests$Member@df9f5f@name: namji
         * false
         * false
         *
         * member1 = com.study.java8.object.ObjectTests$Member@71f4dd@name: namji
         * member2 = com.study.java8.object.ObjectTests$Member@df9f5f@name: namji
         * false
         * true
          */
    
      }
    
      static class Member {
    
        public String getName() {
          return name;
        }
        public void setName(String name) {
          this.name = name;
        }
    
        public Member(String name) {
          this.name = name;
        }
    
    
        private String name;
    
        @Override
        public boolean equals (Object object) {
          // 1. equals의 인자가 자기 자신인지 확인
          if (this == object) return true;
          // 2. equals의 인자가 null인지 확인
          if (object == null) return false;
          // 3. instanceof 연산자로 인자의 자료형이 정확한지 확인
          if (!(object instanceof Member)) return false;
    
          Member m = (Member) object;
          // 4. 값이 null일 경우도 고려하여 리턴
          return (name == null ? m.getName() == null : name.equals(m.getName()));
        }
    
        @Override
        public String toString() {
          return super.toString() + "@name = " + name;
        }
      }
    }