같은 기능이 요청올 때 마다 매번 새로운 인스턴스를 생성하기 보다는 하나의 객체가 재사용되는게 나을때가 있다.
불변객체라면 언제든 재사용할 수 있다.
문자열을 변수에 할당 할 때
String s = new String ("문자열");
String s2 = "문자열";
생성자 방식은 매번 인스턴스를 만들지만
리터럴 방식은 하나의 String 인스턴스를 사용한다. 또한 이 방식은 똑같은 문자열을 선언할 경우 fly weight pool에 있는 문자열 참조값을 같이 사용할 수 있다.
Boolean 클래스의 생성자 같은 경우 deprecated 되어 있으므로 정적 팩터리 메서드인 Boolean.valueOf(string)을 사용하는 것이 좋다.
생성 비용이 비싼 객체 (CPU나 메모리 많이 잡아먹는 애)라면 더욱이 캐싱하여 재사용하길 권한다.
캐싱(Caching)이란
캐시(cache)는 컴퓨터 과학에서 데이터나 값을 미리 복사해 놓는 임시 장소를 가리킨다. 캐시는 캐시의 접근 시간에 비해 원래 데이터를 접근하는 시간이 오래 걸리는 경우나 값을 다시 계산하는 시간을 절약하고 싶은 경우에 사용한다. 캐시에 데이터를 미리 복사해 놓으면 계산이나 접근 시간 없이 더 빠른 속도로 데이터에 접근할 수 있다.
캐싱은 이러한 캐시라는 작업을 하는 행위(행동)이다.
정규표현식을 사용하여 문자열을 확인 할 때
static boolean isRomanNumeral(String s) {
return s.matches("^(?=.)M*(C[MD]|D?C{0,3})(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})$");
}
String 객체의 matches 메서드는 내부에서 Pattern 인스턴스를 사용하여 들어온 문자열을 정규표현식으로 확인한다.
사용하기 편하지만 한번 사용하고 버려져 가비지 컬렉션 대상이 되기때문에 반복해 사용해야 하는 상황에서는 적합하지 않다. Pattern 클래스는 인스턴스 생성 비용이 높아 자주 사용하려면 정적 메서드로 만들어 캐싱하여 인스턴스 재사용한다.
private static final Pattern ROMAN = Pattern.compile("^(?=.)M*(C[MD]|D?C{0,3})(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})$");
static boolean isRomanNumeral(String s ) {
return ROMAN.matcher(s).matches();
}
그리고 primitive type을 사용할 때 인자값이 Object 객체로 넣어야 하는 경우 Wrapper 클래스를 사용하기도 하는데
primitive type으로 사용해도 되는데 쓸데없이 Wrapper 클래스로 사용하거나
사용하다 잘못 AutoBoxing이 일어나 불필요한 객체가 생성되지 않도록 주의해야한다.
private static long sum(){
// 변수 선언시 long 기본 타입이 아닌 Long 객체로 선언하여
Long sum = 0L;
for(long i = 0; i <= Integer.MAX_VALUE; i++){
// 더해질 때마다 Long 으로 오토박싱 되고 있음
sum += i;
return sum
}// end of for
}
참고
-인프런 이펙티브 자바 완벽 공략
'개인룸 > 도윤' 카테고리의 다른 글
item10. equals는 일반 규약을 지켜 재정의하라. (0) | 2023.01.29 |
---|---|
Item8. finalizer와 cleaner 사용을 피하라 (0) | 2023.01.16 |
아이템 7 다 쓴 객체 참조를 해제하라 (1) | 2023.01.15 |
아이템5 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라 (0) | 2023.01.08 |
아이템 4 인스턴스화를 막으려거든 private 생성자를 사용하라 (0) | 2023.01.08 |