"기본형을 제외한 모든 것은 객체다"
자바에서 모든 클래스의 최상위 부모 클래스는 항상 java.lang 패키지에 있는 Object 클래스이며 명시적이 아닌 묵시적인 상속관계이다. (부모가 없어도 따로 extends를 안 해도 된다)
※ Object 배열을 활용하면 세상 모든 타입의 객체를 다 담을 수 있다
[Object 클래스가 제공하는 대표적인 기능]
1. 객체의 정보를 제공하는 toString()
2. 객체의 같음을 비교하는 equals(Object obj)
3. 객체의 클래스 정보를 제공하는 getClass()
4. 객체의 해시 코드를 반환하는 hashCode()
5. 멀티스레드 메서드 notify(), notifyAll(), wait()
6. 객체를 복사하는 clone() - 잘 사용하지 않기에 다루지는 않겠다
1. toString() 메서드: 객체의 정보를 문자열 형태로 제공하는 메서드
정확하게 기본 구현에서는 객체의 클래스 이름과 객체의 해시 코드를 포함한 문자열을 반환한다
public String toString() {
// 해시코드를 16진수로 변환
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
이 메서드는 Object 클래스에 정의되므로 모든 클래스에서 상속받아 사용할 수 있다. (풀어서 쓰면 Object.toString() 이다.)
디버깅과 로깅에 유용하게 사용된다.
※ 해시코드란?
ㅇtoString() 오버라이딩
Object.toString() 메서드가 클래스 정보와 참조값을 제공하지만 이 정보만으로는 객체의 상태를 적절히 나타내지 못한다. 그래서 보통 toString()을 재정의(오버라이딩)해서 보다 유용한 정보를 제공하는 것이 일반적이다.
실무에서 toString()의 재정의가 필요한 상황이 온다면 IDE를 이용해서 편리하게 생성하도록 하자
IntelliJ를 포함한 대부분의 IDE는 정확한 toString() 메서드를 자동으로 만들어준다.
※ generator 단축키: ⌘N (macOS) / Alt+Insert (Windows/Linux)
ㅇSystem.out.println()
우리가 지금까지 흔히 사용했던 System.out.println() 메서드는 Object 매개변수를 사용하고 내부에서 toString()을 호출한다. 따라서 여태껏 System.out.println()를 사용하면 세상의 모든 객체의 정보(toString())를 편리하게 출력할 수 있었던 것이다.
2. equals(Object obj) 메서드: 동등성을 비교해 주는 메서드
// Object 클래스가 기본으로 제공하는 equals() 메서드는 == 으로 동일성 비교를 제공한다
public boolean equals(Object obj) {
return (this == obj);
}
동일성(Identity): == 연산자를 사용해서 두 객체의 참조가 동일한 객체를 가리키고 있는지 확인
동등성(Equality): equals() 메서드를 사용하여 두 객체가 논리적으로 동등한 지 확인
"동일"은 완전히 같음을 의미한다. 반면, "동등"은 같은 가치나 수준을 의미하지만 그 형태나 외관 등이 완전히 같지는 않을 수 있다.
쉽게 이야기해서 동일성은 물리적으로 같은 메모리에 있는 객체 인스턴스인지 참조값을 확인하는 것이고, 동등성은 논리적으로 같은지 확인하는 것이다.
동등성이라는 개념은 각각의 클래스마다 다르다. 어떤 클래스는 주민등록번호를 기반으로 동등성을 처리할 수 있고, 어떤 클래스는 고객의 연락처를 기반으로 동등성을 처리할 수 있다. 어떤 클래스는 회원 번호를 기반으로 동등성을 처리할 수 있다. 따라서 동등성 비교를 사용하고 싶으면 equals() 메서드를 재정의해야 한다. 그렇지 않으면 Object 클래스는 동일성 비교를 기본으로 제공한다.
"기본적으로 자바에서 제공하는 클래스들은 모두 오버라이딩이 되어 있다 e.g. String 클래스의 equals()"
[equals() 메서드를 구현할 때 지켜야 하는 규칙 5가지]
- 반사성(Reflexivity): 객체는 자기 자신과 동등해야 한다. ( x.equals(x)는 항상 true )
- 대칭성(Symmetry): 두 객체가 서로에 대해 동일하다고 판단하면, 이는 양방향으로 동일해야 한다. ( x.equals(y)가 true 이면 y.equals(x)도 true)
- 추이성(Transitivity): 만약 한 객체가 두 번째 객체와 동일하고, 두 번째 객체가 세 번째 객체와 동일하다면, 첫 번째 객체는 세 번째 객체와도 동일해야 한다
- 일관성(Consistency): 두 객체의 상태가 변경되지 않는 한, equals() 메서드는 항상 동일한 값을 반환해야 한다
- null에 대한 비교: 모든 객체는 null과 비교했을 때 false를 반환해야 한다
이 5가지를 모두 다 외울 필요는 없다. 실무에서 equals의 재정의가 필요한 상황이 온다면 IDE를 이용해서 편리하게 생성하도록 하자!
IntelliJ를 포함한 대부분의 IDE는 정확한 equals() 메서드를 자동으로 만들어준다.
※ generator 단축키: ⌘N (macOS) / Alt+Insert (Windows/Linux)
// 재정의 - 정확한 equals 구현, 인텔리제이 IDE 자동 생성
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return Objects.equals(변수, 객체.변수);
}
3. getClass() 메서드: 클래스에 대한 메타데이터를 조회
https://claremont.tistory.com/entry/Java-API-Class-%ED%81%B4%EB%9E%98%EC%8A%A4
4. hashCode() 메서드: 모든 객체 각각의 숫자 해시코드를 제공하는 메서드
자바는 모든 객체가 자신만의 해시 코드를 표현할 수 있는 기능을 제공한다. 해시 인덱스를 사용하는 해시 자료구조는 데이터 추가, 검색, 삭제의 성능이 O(1)로 매우 빨라 많은 곳에서 자주 사용된다. 그런데 해시 자료구조를 사용하려면 정수로 된 숫자값인 해시 코드가 필요하다. 자바에는 정수 int, Integer 뿐만 아니라 char, String, Double, Boolean 등 수많은 타입이 있다. 뿐만 아니라 개발자가 직접 정의한 Member, User와 같은 사용자 정의 타입도 있다. 이 모든 타입을 해시 자료구조에 저장하려면 모든 객체가 숫자 해시코드를 제공할 수 있어야 한다.
5. 멀티스레드 메서드:
참고 및 출처: 김영한의 실전 자바 - 중급 1편, 중급 2편
'Language > Java' 카테고리의 다른 글
[Java API] StringBuilder 클래스 (0) | 2024.08.22 |
---|---|
[Java API] String 클래스 주요 메서드 정리 (0) | 2024.08.22 |
[Java API] java.lang 패키지 주요 클래스와 인터페이스 정리 (0) | 2024.08.20 |
JAVA 16 - instanceof 신기능(Pattern Matching for instanceof) (0) | 2024.08.11 |
[Java] 오버라이딩 조건 5가지 (0) | 2024.08.09 |