IT 관련 책 정리 및 후기/Java Effective E3 9

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

자바 라이브러리에는 close 메서드를 호출해 직접 닫아줘야 하는 자원들이 많은데, 자원을 닫기 위해서는 try-finally 보다 try-with-resources를 사용하여 닫아야 한다. -> 자원이 둘 이상이면 try-finally 방식은 너무 지저분하다 -> finally 구문에서도 예외가 발생할 수 있고 이전에 try 구문에서도 예외가 발생할 수 있으므로 나중에 나온 예외가 이전 예외를 덮어버려서 어떠한 예외에서 에러가 발생했는지 파악하기 어렵다. -> try-with-resources를 사용할 경우 { } 안에 있는 예외만 발생하게 되어 예외를 확실히 알 수 있다. 전통적인 자원 닫힘 보장 수단 - try-finally - 예외가 발생하거나 메서드에서 반환되는 경우를 포함 try-with-re..

[Item 8] finalizer와 cleaner 사용을 피하라

자바 제공 객체 소멸자 1. finailzer 2. cleaner 위 두개의 객체 소멸자 사용 시 인스턴스의 자원 회수가 제멋대로 지연될 수 있다. 상태를 영구적으로 수정하는 작업에서는 절대 finalizer나 cleaner에 의존해서는 안된다. 객체 소멸자 대체 방법 - AutoCloseable 구현 해주고, 클라이언트에서 인스턴스를 다 쓰고 나면 close 메서드를 호출 - 일반적으로 예외가 발생해도 제대로 종료되도록 try-with-resources 사용 finailzer과 cleaner 활용 방법 1. 소유자가 close 메서드를 호출하지 않는 것에 대비한 안전망 역할 - 두 객체 소멸자가 호출 된다는 보장은 없지만, 클라이언트가 하지 않은 자원 회수를 늦게라도 해주는 안정망 역할 2. 네이티브 ..

[Item 7] 다 쓴 객체 참조를 해제하라

가비지 컬렉션 (GC) - 다 쓴 객체(사용하지 않는 객체)를 알아서 회수해 가는 자바 메모리 관리 기능 가비지 컬렉션이 객체를 회수하지 못하는 경우 - 참조된 객체가 하나라도 있다면 해당 객체 뿐만 아니라 그 객체가 참조하는 모든 객체는 회수 될 수 없다 그래서 단 몇개의 객체가 매우 많은 객체를 회수하지 못하게 할 수 있고 잠재적으로 성능에 악영향을 줄 수 있다. 해결방안 1. 해당 참조를 다 사용하였을 떄 null 처리(참조 해제) 하면 된다. - 프로그래머는 비활성 영역이 되는 순간 null 처리를 해서 해당 객체는 더이상 쓰이지 않을 것임을 가비지 컬렉션에 알려야 한다. -> 실수로 null 처리한 참조를 사용하게 된다면 프로그램은 NullPointerException 예외를 발생시켜 종료된다...

[ITEM 6] 불필요한 객체 생성을 피해라

똑같은 기능의 객체 생성 - 똑같은 기능의 객체를 매번 생성하기 보다는 객체 하나를 재사용 하는 편이 나은 경우가 많다. EX) String s = new String("lee"); -> 실행될 떄마다 String 인스턴스를 새로 만든다. 단순 lee라는 문자열을 반환하는 것임에도 불구하고 불필요한 인스턴스 생성이 일어남 String s = "lee"; - 새로운 인스턴스를 매번 만드는 대신 하나의 String 인스턴스를 사용한다. 생성비용이 비싼 객체 - 반복이 필요하다면 캐싱하여 재사용 권장 - 객체 생성 비용이 비싼 객체의 인스턴스를 사용하는 클래스의 초기화 과정에서 직접 생성하여 캐싱함 private static final Pattern ROMAN = Pattern.compile("정규식") st..

[ITEM 5] 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라

사용하는 자원에 따라 동작이 달라지는 클래스에는 정적 유틸리티 클래스나 싱글턴 방식이 적합하지 않다. - 대신 클래스가 여러 자원 인스턴스를 지원해야 하며, 클라이언트가 원하는 자원을 사용해야 한다. -> 이 조건을 만족하는 간단한 패턴은 인스턴스를 생성할 떄 생성자에 필요한 자원을 넘겨주는 방식 (의존 객체 주입) 의존 객체 주입 - 클래스를 생성할 떄 의존 객체를 사전에 주입해준다 - 인스턴스를 생성할 떄 생성자에 필요한 자원을 넘겨주는 방식 . 의존 객체 주입의 변형으로는 생성자에 자원 팩터리를 넘겨주는 방식이 있다 (팩터리 메서드 패턴) - 클라이언트는 자신이 명시한 타입의 하위 타입이라면 무엇이든 생성할 수 있는 팩터리를 넘길 수 있다. - 유연성과 테스트 용이성을 개선해주기도 하지만, 의존성이..

[ITEM 4] 인스턴스화를 막으려거든 private 생성자를 사용하라

정적 메서드와 정적 필드만을 담은 클래스를 만드는 이유 1. 기본 타입이나 배열 관련 메서드들을 모아놓을 수 있다. 2. final 클래스와 관련한 메서드들을 모아놓을 떄도 사용한다. - final 클래스를 상속해서 하위 클래스에 메서드를 넣는 건 불가능하기 때문이다. ⁕ 추상클래스로 만드는 것으로는 인스턴스화를 막을 수 없다 - 하위 클래스를 만들어 인스턴스화하면 그만이기 때문 인스턴스화를 막는 방법 - 컴파일러가 기본 생성자를 만드는 경우는 오직 명시된 생성자가 없을 떄이니, private 생성자를 추가하면 클래스의 인스턴스화를 막을 수 있다. - 명시적 생성자가 private이니 클래스 바깥에서는 접근할 수 없다. 위와 같은 방식은 상속을 불가능 하게 하는 효과도 있다 -> 모든 생성자는 명시적이든..

[Item3] private 생성자나 열거 타입으로 싱글턴임을 보증하라

싱글턴이란? - 인스턴스를 오직 하나만 생성할 수 있는 클래스 - 설계상 유일해야 하는 시스템 컴포넌트 - 클래스를 싱글턴으로 만들면 이를 사용하는 클라이언트를 테스트하기가 어려워질 수 있다 싱글턴 생성 방식 1 - private 기본 생성자를 생성하여 생성자를 외부로 부터 감춘다. - public static final 필드를 선언하고 필드 변수가 초기화 될떄 딱 한번 호출 한다. EX) public static final Elvis INSTANCE = new Elvis(); Elvis.INSTANCE - 클래스가 초기화 될 떄 만들어진 인스턴스가 전체 시스템에서 하나뿐임이 보장된다. 싱글턴 생성 방식 2 - 정적 팩터리 메서드를 public static 멤버로 제공 EX) private static ..

[Item2] 생성자에 매개변수가 많다면 빌더를 고려하라

클래스에 인스턴스를 만들기 위해서는 매개변수를 입력 받아 클래스를 생성해야한다 하지만 점점 많은 매개변수를 받게 될 경우 하나부터 N개의 매개변수에 대한 생성자를 각각 생성해주어야 하고 필요한 생성자를 골라서 생성해야한다. 이렇게 되면 코드상으로도 읽기 어려우며 코드의 양도 많아지게 된다. 점층적 생성자 패턴 - 위와 같은 생성자 생성 패턴을 점층적 생성자 패턴 이라고 하는데 점층적 생성자 패턴 사용 시 타입이 같은 매개변수가 연달아 있으면 매개변수의 순서를 잘못 설정하여 지정해줘도 컴파일러는 알아차리지 못하고 런타임 단계에서 이상한 동작을 하게되어 매개변수가 많을 경우 안좋은 점 이 있다. 자바빈즈 패턴 (JavaBeans Pattern) - 선택 매개변수가 많을 떄 활용하는 패턴으로 Setter를 구..

[Item1] 생성자 대신 정적 팩터리 메서드를 고려하라

정적 팩터리 메소드 (static factory method) 란? - 클래스의 인스턴스를 반환하는 단순한 정적 메서드 EX) 기본 타입인 boolean 값을 받아 Boolean 객체 참조로 변환하여 반환한다. public static Boolean valueOf(boolean b){ return b ? Boolean.TRUE : Boolean.FALSE; } 정적 팩터리 메소드의 장점 1. 이름을 가질 수 있다. - 생성자의 이름과 매개변수 만으로는 객체의 특성을 제대로 설명하지 못하지만, 정적 팩터리는 이름을 지정해 주어 해당 정적 메소드가 어떠한 역할을 해주는지 자세히 정의할 수 있다. 2. 호출될 때 마다 인스턴스를 새로 생성하지 않아도 된다. [Item 17 불변클래스 참고] - 미리 만들어 놓..