<Object 클래스>
1. Object 클래스
- 자바의 최상위 부모 클래스
- 다른 클래스 상속하지 않으면 java.lang.Object 클래스 상속 암시
- Object의 메소드는 모든 클래스에서 사용 가능
2. 객체 비교(equals() 메소드)
public boolean equals(Object obj)
- Object 클래스의 equals 메서드는 == 연산자와 동일
* 물리적 동등성 비교(번지 비교)
- 논리적 동등성 비교 시 재정의 필요
* 물리적으로는 다른 인스턴스이지만 가지는 값이 동일한지 여부 판단
3. 객체 해시코드(hashCode())
- 객체를 식별할 하나의 정수값을 리턴
* 디폴트는 객체의 메모리 번지 이용해 해시코드 리턴
** 개별 객체는 해시코드가 모두 다름
- 논리적 동등 비교시 hashCode() 재정의 필요
* 컬렉션의 Set, Map
** 객체(또는 Key)의 중복 저장 불허
** 논리적 동등성으로 중복 여부 판단
- Key.java
public class Key {
public int number;
public Key(int number){
this.number = number;
}
@Override
public boolean equals(Object obj) {
if(obj instanceof Key) {
Key compareKey = (Key) obj;
if(this.number == compareKey.number) {
return true;
}
}
return true;
}
//@Override
//public int hashCode() {
// return number;
//}
}
- KeyExample.java
public class KeyExample{
public static void main(String[] args) {
//Key 객체를 식별키로 사용해서 String 값을 저장하는 HashMap 객체 생성
HashMap<Key, String> hashMap = new HashMap<Key, String>();
//식별키 "new Key(1)"로 "홍길동"을 저장함
hashMap.put(new Key(1), "홍길동");
//식별키 "new Key(1)"로 "홍길동"을 읽어옴
String value = hashMap.get(new Key(1));
System.out.println(value);
Object obj = new Object();
System.out.println(obj);
System.out.println(obj.hashCode());
}
}
4. 객체 문자 정보(toString())
- 객체를 문자열로 표현한 값
- String 타입이 지정한 곳에 객체 인스턴스를 배치시 자동 호출
- Object의 디폴트 toString()
* 클래스명@해시코드(인스턴스주소)
Object obj = new Object();
System.out.println(obj.toString());
[실행결과]
java.lang.Object@de6ced
- 일반적으로 클래스의 필드의 값을 출력
* 해당 인스턴스의 내부 정보 확인용
5. 객체 복제(clone())
- 원본 객체의 필드 값과 동일한 값을 가지는 새로운 객체를 생성
- 복제의 종류
* 얕은 복제(thin clone) : 필드 값만 복제(기본 타입은 값이 복사, 참조 타입은 참조 값이 복사 - 공유)
* 깊은 복제(deep clone) : 참조의 대상까지 복제
- Object의 clone() 메서드
* 동일한 필드 값을 가지는 얕은 복제된 객체 리턴
** 따로 clone() 메서드를 재정의할 필요는 없음
* java.lang.Cloneable 인터페이스 구현 객체만 복제 가능
** 인터페이스 구현없이 clone() 호출시 CloneNotSupportedException 발생
** clone() 메서드 호출시 예외처리 필수
try {
Object obj = clone();
} catch(CloneNotSupportedException e) {
// 예외 처리
}
* 깊은 복제가 필요한 경우 clone() 메서드 재정의
** 참조 객체도 복제
- Member.java : 복제할 수 있는 클래스 정의
public class Member implements Cloneable {
public String id;
public String name;
public String password;
public int age; public boolean adult;
public Member(String id, String name, String password, int age, boolean adult) {
this.id = id;
this.name = name;
this.password = password;
this.age = age;
this.adult = adult;
}
public Member getMember() {
Member cloned = null;
try {
cloned = (Member) clone(); // 형변환 필요
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
return cloned;
}
}
- MemberExample.java : 복제 객체를 변경하더라도 원본 객체를 변화 없음.
public class MemberExample {
public static void main(String[] args) {
//원본 객체 생성
Member original = new Member("blue", "홍길동", "12345", 25, true);
//복제 객체를 얻은 후에 패스워드 변경
Member cloned = original.getMember();
cloned.passwd = "67890";
System.out.println("[복제 객체의 필드값]");
System.out.println("id: " + cloned.id);
System.out.println("name: " + cloned.name);
System.out.println("password: " + cloned.password);
System.out.println("age: " + cloned.age);
System.out.println("adult: " + cloned.adult);
System.out.println();
System.out.println("[원본 객체의 필드값]");
System.out.println("id: " + original.id);
System.out.println("name: " + original.name);
System.out.println("password: " + original.password);
System.out.println("age: " + original.age);
System.out.println("adult: " + original.adult);
}
}
6. 객체 소멸자(finalize())
- GC(Grabage Collector)는 객체를 소멸하기 직전 객체 소멸자(finalize()) 실행
- Object의 finalize()는 기본적으로 실행 내용이 없음
- 객체가 소멸되기 전에 실행할 코드가 있다면?
* Object의 finalize() 재정의
- 될 수 있으면 소멸자는 사용하지 말 것
* GC는 메모리의 모든 쓰레기 객체를 소멸하지 않음
* GC의 구동 시점이 일정하지 않음.
<Objects 클래스>
1. Objects 클래스
- Object의 유틸리티 클래스
리턴타입 | 메소드(매개변수) | 설명 |
int | compare(T a, T b, Comparator<T> c) | 두 객체 a와 b를 Comparator를 사용해서 비교 |
boolean | deepEquals(Object a, Object b) | 두 객체의 깊은 비교(필드도 비교) |
boolean | equals(Object a, Object b) | 두 객체의 얕은 비교(번지만 비교) |
int | hash(Object... values) | 매개값이 저장된 배열의 해시코드 생성 |
int | hashCode(Object o) | 객체의 해시코드 생성 |
boolean | isNull(Object obj) | 객체가 널인지 조사 |
boolean | nonNull(Object obj) | 객체가 널이 아닌지 조사 |
T | requireNonNull(T obj) | 객첵 널인 경우 예외 발생 |
T | requireNonNull(T obj, String message) | 객체가 널인 경우 예외 발생(주어진 예외 메세지 포함) |
T | requireNonNull(T obj, Supplier<String> messageSupplier) | 객체가 널인 경우 예외 발생(람다식이 만든 예외 메세지 포함) |
String | toString(Object o) | 객체의 toString() 리턴값 리턴 |
String | toString(Object o, String nullDefault) | 객체의 toString() 리턴값 리턴, 첫 번째 매개값이 null 일 경우 두 번째 매개값 리턴 |
2. 객체 비교
- Objects.compare(T a, T b, Comparator<T> c)
* a, b 두 객체를 비교자(c)로 비교해 int값 리턴
** 논리적으로 a-b의 결과 리턴
** 음수 : a < b
** 0 : a == b
** 양수 : a > b
- Comparator<T> 인터페이스
* 제너릭 인터페이스 타입
* T 타입의 객체를 비교하는 compare(T a, T b) 메소드 가짐
public interface Comparator<T> {
int compare(T a, T b)
}
3. 동등 비교(equals()와 deepEquals())
- 두 객체의 동등 비교
- Objects.equals(Object a, Object b)
- deepEquals(Object a, Object b)
* 비교할 객체가 배열일 경우 항목 값까지도 비교
4. 해시코드 생성(hash(), hashCode())
- Objects.hash(Object... values)
* 매개값으로 주어진 값들 이용해 해시 코드 생성하는 역할
* Arrays.hashCode(Object[]) 호출해 해시코드 얻어 리턴
* 클래스의 hashCode()의 리턴값 생성할 때 유용하게 사용
@Override
public int hashCode() {
return Objects.hash(field1, field2, filed3);
}
- Objects.hashCode(Object o)
* o.hashCode() 호출하고 받은 값 리턴
* 매개값이 null 이면 0 리턴
5. 널 여부 조사(isNull(), nonNull(), requireNonNull())
- Objects.isNull(Object obj)
* obj가 null일 경우 true
- Objects.nonNull(Objcet obj)
* obj가 non null일 경우 true
- requireNonNull()
6. 객체 문자정보(toString())
- 객체의 문자정보 리턴
toString(Object obj);
toString(Objcet obj, String nullDefault);
* 첫 번째 매개값이 not null
** toString()으로 얻은 값을 리턴
* null이면
** "null" 또는 두 번째 매개값인 nullDefault 리턴