-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Labels
Description
section: 6장
- 아이템 61. 박싱된 기본 타입보다는 기본 타입을 사용하라
- 아이템 62. 다른 타입이 적절하다면 문자열 사용을 피하라
- 아이템 63. 문자열 연결은 느리니 주의하라
- 아이템 64. 객체는 인터페이스를 사용해 참조하라
🍵 서론
이번 아이템은, 다들 한 번쯤 들어봤을 만한 기본적인 내용을 이야기하고 있다. 아이템별로 핵심 내용만을 빠르게 정리해보자 !
🌒 본론
1️⃣ 기본 타입을 사용해라
💡 기본 타입을 쓸 수 있다면, 기본 타입을 사용하자
- 기본 타입은 값만 가지지만, 박싱된 기본 타입은
식별성도 가진다. - 기본 타입은 항상 유효한 값을 가지지만, 박싱된 기본 타입은 유효하지 않은
null값도 가질 수 있다. - 기본 타입이 박싱된 기본 타입보다 시간 및 메모리 측면에서 효율적이다.
위의 3가지는, 기본 타입과 박싱된 기본 타입의 차이이다. 오토박싱/언박싱 덕분에 크게 구분없이 기본 타입과 박싱된 기본 타입을 사용할 수 있지만, 예상치 못한 상황에서 문제를 일으키기도 한다.
기본 타입 :
int,double,boolean
박싱된 기본 타입 :Integer,Double,Boolean
Case01. == 비교
(i<j)에서는 오토언박싱되어 30이라는 값이 비교되지만(i==j)에서는 오토언박싱이 일어나지 않고 객체의 식별성을 검사한다.
즉, 박싱된 기본 타입에 == 연산자를 사용하면 오류가 발생하게 된다. 이를 해결하기 위해서는 == 연산자에서도 값을 비교할 수 있도록, 기본 타입으로 변환한 뒤에 값을 비교해야 한다.
Case02. null 초기화
Integer등의 박싱된 기본 타입은, 명시적으로 초기화하지 않을 경우 참조 타입처럼null로 초기화가 된다.- 또한, 기본 타입과 박싱된 기본 타입을 혼용하면 박싱된 기본 타입의 박싱이 자동으로 풀리게 된다.
- 따라서, if문에서 변수 i가 오토박싱되어
null과의 비교가 일어나므로NUllPointerException이 발생한다.
Case03. 성능 저하
➕ 오토박싱/언박싱에서의 성능 저하
- Wrapper 클래스에서 값을 비교하려면
equals()를 사용해야 하고, 이는 객체의 비교이므로 성능 저하 발생 - 오토 박싱을 사용하는 경우, Wrapper 클래스의 새로운 객체가 생성되므로 메모리 할당이나 가비지 컬렉션 등의 부하가 발생
- 참고로, 100만건 기준 약 5배의 성능 차이가 발생
❓ 그렇다면 박싱된 기본 타입은 언제 사용하지?
- 컬렉션의 원소, 키, 값
- 매개변수화 타입이나 매개변수화 메서드의 타입 매개변수
- 리플렉션을 통한 메서드 호출
2️⃣ 문자열보다 적절한 다른 타입을 사용해라
💡 문자열은 진짜 문자열을 나타내는 경우에만 사용하자
- 수치형이라면
int,float,BigInteger등의 적당한 수치 타입으로 변환 - 예/아니오 등의 형태라면 적절한
열거 타입이나boolean으로 변환 - 권한은
key 클래스로 사용
public final class ThreadLocal<T>{
public ThreadLocal();
public void set(T value);
public T get();
}3️⃣ 문자열 연결을 주의해라
💡 문자열을 연결해야 한다면
StringBuilder를 사용하자
String은 불변 객체- 두 문자열을 연결하는 경우, 양쪽 모두를 복사해야하기 때문에 성능 저하가 발생
4️⃣ 객체는 인터페이스로 참조해라
💡 적합한 인터페이스가 있다면 모두 인터페이스로 선언하자
- 유연한 프로그램을 작성할 수 있음
- 예로, 구현 클래스 교체가 필요한 경우 새로운 클래스의 생성자만 호출해주면 코드를 변경할 필요가 없음
// 이전 코드
Set <Son> sonSet = new LinkedHashSet<>();
// 변경 코드
Set <Son> sonSet = new HashSet<>();
// 만약 인터페이스가 아니였다면?
LinkedHashSet<Son> sonSet = new LinkedHashSet<>();선언문 뿐만 아니라, 기존 타입에서만 제공하는 메서드 등을 사용한 경우 컴파일이 되지 않는 문제가 발생한다.
이때, 구현 클래스를 교체할 때는 해당 클래스만이 제공하는 특별한 기능을 사용하는지를 확인해야 한다.
- 만약, 위의 코드에서
LinkedHashSet이 따르는 순서 정책을 사용하고 있었다면?
적합한 인터페이스가 없는 경우
String,BigInteger등의 값 클래스- 클래스 기반으로 작성된 프레임워크가 제공하는 객체
- 인터페이스에는 없는 특별한 메서드를 제공하는 클래스
=> 클래스의 계층 구조 중 필요한 기능을 만족하는 가장 덜 구체적인 클래스를 타입으로 사용해라.
🍃 결론
📌 사용할 수 있다면, 우선적으로 사용해야 할 것들
- 기본 타입
- 적절한 데이터 타입
StringBuilder- 인터페이스

