열두번째날 [기본 API 클래스(1)]
목차
1. 자바 API 도큐먼트
2. java.lang과 java.util 패키지
3. Object 클래스
[1] 자바 API 도큐먼트
* 자바 API(Application Programming Interface)
- 자바에서 기본적으로 제공하는 라이브러리(library)
- 프로그램 개발에 자주 사용되는 클래스 및 인터페이스 모음
* API 도큐먼트
- 쉽게 API를 찾아 이용할 수 있도록 문서화한 것
- HTML 페이지로 작성되어 있어 웹 브라우저로 바로 볼 수 있음
- 자바 11 버전
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/module-summary.html
java.base (Java SE 11 & JDK 11 )
Contains the collections framework, some internationalization support classes, a service loader, properties, random number generation, string parsing and scanning classes, base64 encoding and decoding, a bit array, and several miscellaneous utility classes
docs.oracle.com
[2] java.lang과 java.util 패키지
* java.lang 패키지
- 자바 프로그램의 기본적인 클래스를 담은 패키지
- 포함된 클래스와 인터페이스는 import 없이 사용
- 주요 클래스
클래스 | 용도 | |
Object | 자바 클래스의 최상위 클래스 | |
System | 키보드로 데이터를 입력받을 때 사용 모니터로 출력하기 위해 사용 자바 가상 기계를 종료시킬 때 사용 쓰레기 수집기를 실행 요청할 때 사용 |
|
Class | 클래스를 메모리로 로딩할 때 사용 | |
String | 문자열을 저장하고 여러 가지 정보를 얻을 때 사용 | |
StringBuffer, StringBuilder | 문자열을 저장하고 내부 문자열을 조작할 때 사용 | |
Math | 수학 함수를 이용할 때 사용 | |
Wrapper | Byte, Short, Character, Integer, Long, Float, Double, Boolean |
기본 타입의 데이터를 갖는 객체를 만들 때 사용 문자열을 기본 타입으로 변환할 때 사용 입력값 검사에 사용 |
* java.util 패키지
- 조미료 같은 역할을 하는 클래스들을 담고 있음
클래스 | 용도 |
Arrays | 배열을 조작(비교, 복사, 정렬, 찾기)할 때 사용 |
Calendar | 운영체제의 날짜와 시간을 얻을 때 사용 |
Date | 날짜와 시간 정보를 저장하는 클래스 |
Objects | 객체 비교, 널(null) 여부 등을 조사할 때 사용 |
StringTokenizer | 특정 문자로 구분된 문자열을 뽑아낼 때 사용 |
Random | 난수를 얻을 때 사용 |
[3] Object 클래스
* 자바의 최상위 부모 클래스
- 다른 클래스 상속(extends)하지 않으면 java.lang.Object 클래스 상속하게 됨
- Object 클래스는 필드 없음
- Object 클래스는 메서드들로 구성되어 있음
- Object의 메서드는 모든 클래스에서 사용 가능 : 모든 클래스가 Object를 상속하기 때문
[3.1]객체 비교 : equals() 메서드
public boolean equals(Object obj){...}
- 매개 타입이 Object : 모든 객체가 매개값으로 대입될 수 있음 : 모든 객체는 Object 타입으로 자동타입변환 될 수 있기 때문
- 기본적으로 == 연산자와 동일한 결과 리턴(번지 비교)
- 논리적 동등 위해 오버 라이딩 필요
논리적 동등 : 같은 객체이건 다른 객체이건 상관없이 객체 저장 데이터 동일. 즉, 값을 비교
- Object의 equals() 메서드 : 직접 사용되지 않고, 재정의하여 논리적 동등 비교할 때 이용 : 오버 라이딩
- 예를 들어, Member 객체는 다르지만 id 필드값이 같으면 논리적으로 동등한 객체로 취급하고 싶을 경우 Object의 equals() 메소드를 재정의해서 Id 필드값이 같음을 비교하면 된다.
매개값(비교 객체)이 기준 객체와 동일한 타입의 객체인지 확인한다. instanceof연산자로 기준 객체와 동일한 타입인지 확인 ➡️ 기준 객체 타입으로 강제 타입 변환해서 필드값이 동일한지 검사 ➡️ 동일하다면 true 리턴, 아니면 false 리턴
[3.2] 객체 해시 코드: hashCode()
* 객체를 식별할 하나의 정수 값
* 객체의 메모리 번지 이용해 해시 코드 만들어 리턴 : 개별 객체는 해시 코드가 모두 다름
* 논리적 동등 비교 시 hashcode() 오버 라이딩의 필요
- 컬렉션 프레임워크의 HashSet, HashMap, HashTable과 같은 클래스는 두 객체가 동등한 객체인지 판단할 때 아래와 같은 과정을 거침
- 컬렉션 프레임워크 : 객체를 모아놓은 저장소
- HashCode()리턴값 같음 : 객체의 주소가 같다는 것
- equals()리턴값 같음 : 객체에 저장된 값이 같다는 것
* 예제 설명
- Map : key - Object 쌍으로 저장시키는 저장소 : 파이썬의 사전 / 배열은 인덱스 값으로 비교, 맵은 키 값으로 비교
- put은 값을 저장 / get은 값을 꺼내옴
- Key 클래스 : equals() 메소드를 재정의 ➡️ number 필드값이 같으면 true 리턴/hashCode()메소드 재정의X ➡️ Object의 메소드 사용
- KeyExample : HashMap의 식별키로 Key 객체를 사용하면 저장된 값을 찾아오지 못함. number 필드값이 같더라도 hashCode() 메소드에서 리턴하는 해시코드가 다르기 때문에 다른 식별키로 인식하기 때문
//hashCode() 메소드를 재정의하지 않음
public class Key {
//필드
public int number;
//생성자
public Key(int number) {
this.number = number;
}
//Object의 equals()메서드 오버라이드
//새로 만든 객체와 key의 number 값이 같다면 true 리턴
@Override
public boolean equals(Object obj) {
if(obj instanceof Key) {
Key compareKey = (Key) obj;
if(this.number == compareKey.number) {
return true;
}
}
return false;
}
}
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);
}
}
따라서 의도한 대로 "홍길동"을 읽으려면 재정의한 hashCode() 메소드를 Key 클래스에 추가해줘야 함. hashCode()의 리턴값을 number 필드값으로 했기 대문에 저장할 때의 "new Key(1)"과 읽을 때의 "new Key(1)"은 같은 해시코드가 리턴됨
저장할 때의 new Key(1)과 읽을 때의 new Key(1)은 사실 서로 다른 객체이지만 HashMap은 hashCode()의 리턴값과 같고, equals()리턴값이 true가 나오기 때문에 동등 객체로 평가. 즉, 같은 식별키로 인식한다. 객체의 동등 비교를 위해서 Object의 equals()메소드만 재정의하지 말고 hashCode() 메소드도 재정의해서 논리적 동등 객체일 경우 동일한 해시코드가 리턴되도록 해야 함.
public class Key_add{
...
@Override
public int hashCode() {
return number;
}
[3.3] 객체 문자정보: toString()
* 객체를 문자열로 표현한 값
* Object 클래스의 toString() 메소드는 객체의 문자 정보 리턴 : "클래스명@16진수해시코드"
* 일반적으로 의미 있는 문자정보가 나오도록 재정의
- Date 클래스 : 현재 시스템의 날짜와 시간 정보 리턴
- String 클래스 : 저장하고 있는 문자열 리턴
* System.out.println(Object) 메소드 : Object의 toString()의 리턴값 출력
[3.4] 객체 복제 : clone()
얕은 복제(thin clone)
* 단순히 원본 객체의 필드값과 동일한 값을 가지는 새로운 객체를 생성하는 것 : 원본 객체를 안전하게 보호
* 필드가 기본 타입일 경우에 값 복사만
* 필드가 참조 타입일 경우엔 값 주소 복사만
* 원본 객체는 반드시 java.lang.Cloneable 인터페이스를 구현하고 있어야 함 : 클래스 설계자가 복제를 허용한다는 의도적 표시를 위해
* 구현하지 않으면 CloneNotSupportedException 예외가 발생
* 예외 처리가 필요한 메소드이기 때문에 try-catch 구문이 필요함
* 단점 : 원본 객체의 필드& 복제 객체 필드는 같은 객체를 참조함. 참조 타입은 값의 주소만 복사되기 때문에, 만약 복제 객체에서 참조 객체를 변경하면 원본 객체도 변경된 객체를 가지게 됨
깊은 복제(deep clone)
* 얕은 복제의 단점을 없애서, 참조하고 있는 객체도 함께 복제하는 것을 말함 : 객체의 값까지 함께 복사
* 원본 객체를 깊은 복제했을 경우, 참조하는 배열 객체도 복제된다는 것을 보여줌 (위의 그림)
[3.5] 객체 소멸자 : finalize()
* 쓰레기 수집기(Garbage Collector)는 객체를 소멸하기 직전 객체 소멸자(finalize())를 실행
* Object의 finalize()메소드는 기본적으로 실행 내용이 없음
* 만약 객체가 소멸되기 전에 마지막으로 사용했던 자원(데이터 연결, 파일 등)을 닫고 싶거나, 중요 데이터를 저장하고 싶다면 Object의 finalize()를 재정의할 수 있다.
* 될 수 있으면 사용하지 말 것
- 메모리의 상태를 보고 일부만 소멸.
- 메모리가 부족하고 CPU가 한가할 때 JVM에 의해 자동으로 실행됨
- 쓰레기 수집기(Garbage Collector)는 메모리의 모든 쓰레기 객체를 소멸하지 않음
- 쓰레기 수집기의 구동 시점이 일정하지 않음
equals는 반드시 알아둘 것
hashcode
tostring이제일 많이 사용
clone, deepclone, finalize는 앞으로 안볼듯