Skip to content

Instantly share code, notes, and snippets.

@kth496
Created February 2, 2021 12:36
Show Gist options
  • Save kth496/1d6906d43775e76bd0956be228f8f83d to your computer and use it in GitHub Desktop.
Save kth496/1d6906d43775e76bd0956be228f8f83d to your computer and use it in GitHub Desktop.
이펙티브 자바 아이템 6

이펙티브 자바 아이템 6 - 불필요한 객체 생성을 피하라

똑같은 기능의 객체는 반복적으로 생성할 이유가 없다. 본문에서는 다음과 예시 코드를 제시한다.

    String s = new String("bikini");
    
    String s = "bikini";

명시적으로 new를 사용해서 문자열 객체를 만드는 행위는 무의미하며 성능에 악영향만 끼친다. 개선된 코드는 문자열 리터럴을 사용하며, 동일한 값에 대해 모든 객체가 똑같다는 사실이 보장된다. 리터럴이란? JLS 에서는 다음과 같이 설명한다.

A literal is the source code representation of a value of a primitive type (§4.2), the String type (§4.3.3), or the null type (§4.1).


public class Main {
    public static void main(String[] args) {
        String id = "taehongkim";
        String id2 = new String("taehongkim");
        String id3 = "taehongkim";
        System.out.println(id.equals(id2));  // true
        System.out.println(id == id2);       // false
        System.out.println(id == id3);       // true
    }
}

위 코드의 실행결과는 리터럴을 사용해서 얻을 수 있는 이득을 확실하게 보여준다. 문자열 비교에서 == 연산자가 권장되지 않는 방법이지만, 메모리 주소 비교를 위해서 위와 같이 작성했다.


앞서 아이템 1에서 정적 팩터리 메서드에 대해 다뤘다. 정적 팩터리 메서드의 장점으로 매번 새로운 객체를 생성하지 않아도 된다는 점이 언급되었다. 이는 지금 다루는 아이템 6 - 불필요한 객체 생성을 피하라는 조언과 일맥상통한다.

    @Deprecated(
        since = "9"
    )
    public Boolean(boolean value) {
        this.value = value;
    }

Boolean 클래스는 정적 팩터리 메서드인 valueOf()를 가지며, 덕분에 새로운 객체를 전혀 생성하지 않고 인스턴스를 재활용할 수 있다. 자바 9 이후로는 위 코드와 같이 Boolean 클래스의 생성자가 deprecated 되었다. 불필요한 객체 생성을 하지 않는 쪽으로 발전하는 것이다.


    static boolean isRomanNumeral(String s) {
        return s.matches("<regex>")
    }

동일한 값을 가지는 객체가 반복적으로 생성되는 것과는 반대로, 값비싼 객체를 재활용하는 방법도 생각해볼 수 있다.

위 코드는 정규표현식을 사용해서 주어진 문자열이 매칭되는지 확인하는 예제 코드이다. 본문에 의하면 이 코드에서 매칭을 위해 사용되는 Pattern 객체는 한 번 사용되고 곧바로 가비지 컬렉션 대상이 된다.

동일한 패턴으로 여러 문자열을 매칭시켜야하는 상황에서 큰 성능 손해가 발생할 가능성이 존재한다. 따라서 Pattern 객체를 재사용할 가능하도록 상수로 꺼내는 방법을 제안하고 있다.

이후로 몇 가지 내용이 더 등장하지만, 아직은 자세히 짚어보지 않아도 될 내용이라고 생각한다.

불필요한 객체 생성을 어떻게 막을 수 있을까? 어떤 객체가 반복적으로 사용되는지 짚어보고, 불변 객체로 만들 수 있는지를 고려하여 객체 생성으로 발생하는 성능 손해를 개선할 수 있다.

@eyabc
Copy link

eyabc commented Feb 3, 2021

  • Object 문자열은 객체를 생성하는 방식이기 때문에 역시 비용이 더들고, primitive 문자열은 문자열값이 같으면 하나의 객체를 사용한다는 사실이 흥미로웠습니다.
  • 문자열 비교에 대해서는 equels 와 == 의 차이를 알게 되었습니다!
public class Main {
    public static void main(String[] args) {
        String id = "taehongkim";
        String id2 = new String("taehongkim");
        String id3 = "taehongkim";
        System.out.println(id.equals(id2));  // true
        System.out.println(id == id2);       // false
        System.out.println(id == id3);       // true
    }
}
  • Boolean 의 deprecated 된 내용에 대해서도 더 알게 되었습니다

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment