📘 Effective Java

    [Item 18] 상속보다는 컴포지션(조합)을 사용하라

    Effective Java에서는 상속보다 컴포지션을 사용하라고 하고 있다. 책 내용이 조금 복잡하고 이해를 했더라도 실제 설계를 어떤 방향으로 할 지 감이 안잡힌다. 비슷한 주제로 검색 하더라도 설명이 부실한 경우가 많았다. 추후에 나도 다시 읽을 목적으로 초등학생한테 설명해주는 것 처럼 하나하나 설명 해볼 예정이다! 일단 주제에 대해 다시 짚고 넘어가고 싶다. 상속보다는 컴포지션을 이용하라는 뜻이 상속이라는 기능 자체에 문제가 있어서는 아닐 것이다. 그렇다면 상속은 항상 좋지 않은 선택일까? 상속이 올바른 경우 상속이 올바른 경우는 아래와 같다. 같은 프로그래머가 하위, 상위 클래스를 통제 문서화가 잘된 클래스 확장 목적으로 설계 된 경우 is-a 관계가 확실할 경우 위의 조건에 부합하는 상속은 문제없..

    [Item 9] try-finally보다는 try-with-resources를 사용하라

    Stream, DB Connection, File 등 외부 자원을 이용하는 것들은 해당 자원을 쓰고나면 반납하는 차원에서 close(); 명령어를 써줘야 한다. try-finally 방식 FileInputStream file = null; try { file = new FileInputStream("file.txt"); //파일 로직 }finally{ file.close(); } try-with-resources 방식 try(FileInputStream file = new FileInputStream("file.txt")){ //file 로직 } 자동으로 close 처리를 해준다. 코드가 깔끔해진다는 장점이 있다. 예외 메시지가 더 정확해진다. close 과정에서 예외가 발생해도 try 블록에서 발생한 ..

    [Item 7~8] 다 쓴 객체 참조를 해제하라, finalizer와 cleaner 사용을 피하라.

    [Item 7] 다 쓴 객체 참조를 해제하라 책의 요지와는 별개로 신기했던건 Arrays.copyOf로 배열의 길이를 늘릴 수 있다는 점이다. (워낙 배열을 안쓰기도 해서 몰랐지만 항상 고정 크기인줄만 알았던 배열이 늘어난다는 건 신기했다.) 책에서 설명하는 것은 Stack 구조로 배열을 만들 때 pop 메소드가 일어나는 경우 해당 자리에 있던 객체는 가비지 컬렉터가 회수해가지 않는다고 한다. 그래서 단순히 배열의 요소 위치만 변경해서 사이즈를 줄이는 것 뿐만 아니라 다 쓴 객체를 null 값으로 지정해줘야 객체 참조가 해제가 된다. 이 행위를 해주지 않으면 프로그램은 해당 객체를 계속 들고 있기 때문에 메모리 누수 현상이 일어난다. 결론 Stack 클래스가 대표적으로 메모리 누수현상이 일어나는 케이스라..

    [Item 6] 불필요한 객체 생성을 피하라

    스프링 컨테이너는 기본적으로 싱글톤 패턴이기 때문에 불필요한 객체 생성을 피하도록 구현되어 있다. 다만 개발자가 임의적으로 만드는 bean이 아닌 클래스에서는 싱글톤임을 보증하지 못하는 클래스로 구현할 때가 많은데 이런 부분은 클라이언트 쓰레드마다 무분별하게 객체 생성이 이루어진다(자바 엔터프라이즈 개발에서 스프링 프레임워크가 만들어진 이유이기도 하다.) 한번 쓰고 버려진 객체들은 가비지 컬렉션 대상이 된다. public class RomanNumerals{ private static final Pattern ROMAN = Pattern.compile("^(?=[MDCLXVI])M*D?C{0,4}L?X{0,4}V?I{0,4}$"); public static boolean isRomanNumeral(Str..