TIL/Java

[Java] Effective Java 3/E item 4~6

JoJobum 2023. 5. 28.

item4: 인스턴스화를 막으려거든 private 생성자를 사용해라

정적 멤버만 담은 유틸리티 클래스는 인스턴스로 만들어 쓰는 설계X

하지만 생성자를 명시하지 않으면 자동 생성되기에, private 생성자를 만들어 인스턴스화를 막자

이러한 방법은 상속을 불가능하게 하는 효과도 존재

 

Plus) 추상 클래스로 만드는 것으로 인스턴스화를 막을 수 없음. 왜냐하면 하위 클래스를 만들어 인스턴스화할 수 있기 때문 + 상속하여 사용하라는 의도로 착각될 수 있음

 

item5: 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라

 

하나 이상의 자원에 의존하는 클래스를 만들 때, 사용하는 자원에 따라 동작이 달라지는 클래스에는 정적 유틸리티 클래스나 싱클톤 방식이 적합하지 않음

 

인스턴스를 생성할 때 생성자에 필요한 자원을 넘겨주는 방식, Spring DI 방식 중 생성자 주입 방식

이러한 방식을 사용하면 자원이나 의존 관계에 상관없이 잘 작동하고, 불변을 보장하여 같은 자원을 사용하려는 여러 클라이언트가 의존 객체들을 공유할 수 있음 (멀티 스레드 환경에 적합)

 

item 6: 불필요한 객체 생성을 피하라

 

불변클래스에서는 정적 팩토리 메소드를 사용해 불필요한 객체 생성을 피할 수 있음

Boolean("true") // 객체 생성, Java 9 버전 부터 Deprecated 됨
Boolean.valueOf("true") // 정적 팩토리 메소드 사용

생성이 비싼 객체는 캐싱하여 재사용하자

static boolean isRomanNumeral(String s){
	return s.matches(~~~~) // 정규표현식에 해당하는 유한 상태 머신 만들기에 비용 비쌈
}
public class RomanNumerals{
	private static final Pattern ROMAN = Pattern.compile(~~~~);

	static boolean isRomanNumeral(String s){
		return ROMAN.matcher(s).matches();	// 유한 상태 머신 재사용하기에 반복될수록 성능 개선
	}
}

불필요한 객체를 만들어내는 다른 예로는 오토박싱(auto boxing)

오토박싱은 기본 타입과 박싱된 기본 타입을 섞어 쓸 때 자동으로 상호 변환해주는 기술

의미상은 둘이 차이가 없지만, 성능에서는 아니다

private static long sum(){
	Long sum = 0L; // vs long sum
	for (long i = 0; i <= Integer.MAX_VALUE; i++)
		sum += i;
	
	return sum;
}

Long sum 인 경우 Long 타입인 sum에 long 타입인 i가 더해질 때마다 Long 인스턴스 생성

long sum 인 경우 그렇지 않기에 성능 차이가 발생한다.

고로 박싱된 기본 타입보다는 기본 타입을 사용하고, 의도치 않은 오토박싱이 숨어들지 않게 하자

반응형

'TIL > Java' 카테고리의 다른 글

[Java] Effective Java 3/E 4장 item 15~20  (0) 2024.01.18
[Java] Effective Java 3/E 3장 item 10~14  (1) 2023.11.14
[JAVA] Java Version 8 vs 17  (0) 2023.10.21
[Java] Effective Java 3/E item 7~9  (1) 2023.06.13
[Java] Effective Java 3/E item 1~3  (0) 2023.05.26

댓글