[Effective Java] Item06. 불필요한 객체 생성을 피하라
Java

[Effective Java] Item06. 불필요한 객체 생성을 피하라

Item06. 불필요한 객체 생성을 피하라

 

같은 기능을 수행하는 객체를 매번 생성하는 것보다 하나를 재사용하는 편이 나을 때가 많다.

특히, 불변 객체는 언제든 재사용 할 수 있다.

 

! 객체의 재사용에 대한 극단적인 예 로 String type을 들 수 있다.

// 실행될 때마다 새로운 String 인스턴스가 생성됨
String s = new String("hunseong");

// String Constant Pool 영역에서 해당 리터럴을 찾음
// 리터럴이 존재한다면 재사용, 없다면 해당 영역에 리터럴 추가
String s = "hunseong";

 

 

! 정적 팩터리 메서드를 제공하는 불변 클래스에서는 정적 팩터리 메서드를 사용해 불필요한 객체 생성을 피할 수 있다.

// 생성자 - 매번 새로운 인스턴스 생성
// 자바 9에서 Deprecated 지정됨
Boolean(String);

// 정적 팩터리 메서드 - 객체를 재사용
Boolean.valueOf(String);

 

! 인스턴스 생성 비용이 비싼 객체의 경우 캐싱하여 재사용하길 권한다.

 

- 아래 코드는 문자열이 유효한 로마 숫자인지를 정규식을 통해 확인하는 메서드이다.

- String.matches 메서드는 내부에서 새로운 Pattern 인스턴스를 생성한다.

- 즉, isRomanNumeral 메서드를 호출 할 때 마다 새로운 Pattern 인스턴스를 생성한다.
- Pattern 인스턴스는 정규표현식에 해당하는 FSM을 만드므로 인스턴스 생성비용이 높다.

public class RomanNumerals {

    static boolean isRomanNumeral(String s) {
        // String.matches 내부에서 새로운 Pattern 인스턴스를 생성
        return s.matches("^(?=.)M*(C[MD]|D?C{0,3})"
                + "(X[CL]|L?X{0,3})(I[XV]|V?I{0,3})$");
    }
}

 

- 성능 개선을 위해 유효한 로마숫자인지 확인하는 (불변의) 정규식을 표현하는 Pattern 인스턴스를 static 필드로 생성해 캐싱한다.

- 생성한 Pattern 인스턴스를 isRomanNumeral 메서드가 호출될 때마다 재사용한다.

 

public class RomanNumerals {

    // 인스턴스 생성비용이 높은 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();
    }
}

 

! 불필요한 객체를 생성할 수 있는 오토박싱(Auto boxing)에 주의하라.

- 오토박싱(auto boxing) : 기본 타입, 박싱된 기본 타입을 섞어 쓸 때 자동으로 상호 변환해주는 기술

- 아래 메서드와 같이 long을 Long으로 선언함으로써 오토박싱이 동작하여 불필요한 Long 인스턴스가 여러 개 생성된다.

   -> long i 가 Long 타입으로 오토박싱됨

- 이는 성능저하의 엄청난 원인이 된다.

- 박싱된 기본 타입보다는 기본 타입을 사용하고, 의도치 않은 오토박싱을 주의하자.

 

private static long sum() {
    // long이 아닌 Long 타입으로 선언하여 오토박싱에 의해 새로운 Long 인스턴스가 계속 생성된다.
    Long sum = 0L;
    for (long i = 0; i <= MAX_VALUE; i++) {
        sum += i;
    }
    return sum;
}

 

 

소스코드 : https://github.com/HunSeongPark/effective-java/tree/master/src/main/java/item06

 

GitHub - HunSeongPark/effective-java: 책 Effective Java 3/E 공부

책 Effective Java 3/E 공부. Contribute to HunSeongPark/effective-java development by creating an account on GitHub.

github.com