ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [이펙티브 자바] 불필요한 객체 생성을 피하라
    개발 공부/자바 2022. 1. 27. 21:31

    똑같은 객체를 매번 생성하는 것은 불필요하다. 객체 하나를 재사용 하는 것이 더 나을 때가 있다.

    다음 코드로 예를 들어보았다.

    코드

    public class Hi {
    
        public static void main(String[] args) {
    
            String str1 = new String("sangjin");
            String str2 = new String("sangjin");
    
            System.out.println(str1 == str2);
            System.out.println(str1.equals(str2));
        }
    }

    false
    true

    다음과 같이 똑같은 문자열을 사용해도 new를 이용하여 스트링의 인스턴스를 만들어버리면 똑같은 기능을 하는 불필요한 스트링 인스턴스만 많아질 뿐이다. 여기서 new만 없애도

    코드

    public class Hi {
    
        public static void main(String[] args) {
    
            String str1 = "sangjin";
            String str2 = "sangjin";
    
            System.out.println(str1 == str2);
            System.out.println(str1.equals(str2));
        }
    }

    true
    true

    스트링 인스턴스가 똑같은 값을 재사용하는 것을 알 수 있다.

    또한 무거운 객체는 반복적으로 사용할 때 미리 초기화를 해두고 재사용 하는 것이 좋다.

    코드

    	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})$");
            }
            
    /*-------------------------------------------------------------------------------------------------------------------------------*/
           
          	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();
            }

    다음은 백기선님 강의에서 예시로 나온 코드이다. 로마 숫자인지 확인하는 정규식인데 계속 사용할 객체라면 아래와 같이 초기화해서 사용하는 것이 성능면에서 더 뛰어나다.

     

    다음으로 어댑터는 한 구현체를 다른 인터페이스에 맞게 변환시켜주는 패턴을 말한다. 어댑터는 불변 객체라 여러 개를 만들 필요가 없다.

    코드

    public class Hi {
    
        public static void main(String[] args) {
            Map<String, Integer> menu = new HashMap<>();
            menu.put("Burger", 8);
            menu.put("Pizza", 9);
    
            Set<String> names1 = menu.keySet();
            Set<String> names2 = menu.keySet();
    
            names1.remove("Burger");
            System.out.println(names1.size()); // 1
            System.out.println(names2.size()); // 1
            System.out.println(menu.size()); // 1
        }
    }

    다음을 예로 들면 map 인터페이스를 keyset을 호출하여 값을 주었을 때 전부 똑같은 객체이기 때문에 결과 값이 모두 1이 나온다.

    오토박싱은 프리미티브 타입을 레퍼런스 타입으로 자동 변환해주는 것을 말한다.

    프리미티브 타입 - 값을 변수에 대입하여 사용

    레퍼런스 타입 - 값을 변수에 대입하지만 메모리상의 참조 값만 사용

    코드

    public static void main(String[] args) {
        int pri = 1;
        Integer ref = pri;
        System.out.println("ref = " + ref);
    }

    다음 코드가 타입이 달라도 정상적으로 실행된다.

    이것도 객체를 만들기 때문에 좋지 않은 방법이다.

     


    참고

    https://book.naver.com/bookdb/book_detail.nhn?bid=14097515 

     

    이펙티브 자바

    자바 플랫폼 모범 사례 완벽 가이드 - JAVA 7, 8, 9 대응자바 6 출시 직후 출간된 『이펙티브 자바 2판』 이후로 자바는 커다란 변화를 겪었다. 그래서 졸트상에 빛나는 이 책도 자바 언어와 라이브

    book.naver.com

    https://www.youtube.com/watch?v=0yUxPUXS1pM&list=PLfI752FpVCS8e5ACdi5dpwLdlVkn0QgJJ&index=6 

    백기선님 강의

Designed by Tistory.