본문 바로가기

Study with group/Effective Java8

[Item49] 매개변수가 유효한지 검사하라 메서드, 생성자에서 받은 매개변수가 특정 제약에 만족해야 한다면 오류는 발생한 곳에서 잡아야 하며 반드시 *문서화를 해야한다. *문서화 (제약의 설명을 문서화 하고 예외의 경우 @throws 자바독 태그를 사용하여 문서화 할 수 있다.) 매개변수 검사를 제대로 하지 못하면 잘못된 결과, 모호한 예외, 해당 지점 이외에서 발생하는 문제를 초래할 수 있다. 다시 말해 *실패의 원자성을 지키기 위해 매개변수의 검사는 필요하다. *실패의 원자성 (예외를 던지고 난 뒤에도 객체는 상태가 이전 상태와 동일하며 사용가능한 형태로 남아야한다.) Objects Utility Class NullPoniterExceptoin, IndexOutOfBoundsException 등의 예외에 대한 유효성 검사에 도움을 주는 Obj.. 2023. 7. 13.
[Item 7] 다 쓴 객체 참조를 해제하라 객체 참조 해제란 메서드 내에서 사용할 객체를 인스턴스화 하여 로컬 변수에 할당하여 참조하고 사용 후 더 이상 사용하지 않는다고 명시적 null처리로 참조 관계를 끊어주거나 해당 메서드가 종료되면 더 이상 사용하지 않을 인스턴스로 참조 관계를 해지하는 것. 보통은 메서드 종료시 변수가 유효 범위를 벗어나게 되어 더 이상 사용하지 않아 가비지 컬렉터가 참조 관계가 끊어진 객체를 회수하는게 가장 좋지만 그렇지 않은 예외적인 경우도 있다. 책에서 나온 예제 코드를 본다면 package effectiveJava.item7; import java.util.Arrays; import java.util.EmptyStackException; public class Stack { private Object[] eleme.. 2023. 1. 29.
[Item 6] 불필요한 객체 생성을 피하라 같은 기능을 하는 객체는 하나를 재사용하는 방법을 고려해야 한다. Wrapper Class 자바의 wrapper class 인 Byte, Short, Integer 등 이있다. primitive type 을 wrapper class로 변환할때, new와 valueOf를 통한 인스턴스 생성이 있는데, 팩터리 메서드인 valueOf를 이용하게 되면 캐싱을 이용하여 불필요한 객체 생성을 막고 있다. public static Integer valueOf(int i) { if (i >= IntegerCache.low && i 2023. 1. 23.
[Item 5] 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라 의존 객체 주입 (Dependency Injection)을 프레임 워크로 제공하는 Dagger, Guice, Spring 등 있는데 한국의 대부분 자바 개발자에게 친숙하게 다가오는 것은 스프링 프레임워크일 것이다. 스프링을 생각해보면 인터페이스 기반으로 클래스 레벨에서는 의존하지 않고 런타임 시 동적으로 주입받는 역할로 많이 사용되고 있다. 이처럼, 유연성을 확보하고 결합도를 낮춰 주는 등의 장점이 존재한다. 여기서 언급되는 정적 유틸리티 클래스, 싱글턴으로서 구현되면 위의 장점과 반대로 유연하지 못하고 결합도는 높아진다. 유일 객체로 사용된다고 하였을 때는 유연성에 대한 고려는 하지 않아도 되겠다. . 이를 해소하기 위해 final 필드 제거하고 메서드를 통한 다형성을 제공할 수 있지만 멀티 스레드 환.. 2023. 1. 9.
[Item 4] 인스턴스화를 막으려거든 private 생성자를 사용하라 정적인 필드와 메서드를 담은 클래스의 구현은 객체 지향적인 사고는 아니자만, 공통점이 있는 메서드 혹은 팩터리들을 제공할 때 사용되기도 한다. 자바 진영에서 제공하는 기본 타입, 유틸성 인터페이스 등이 있고, 이외로 final 클래스가 있다. 위 예시처럼 정적으로 선언한 만큼 인스턴스 생성하지 못하도록하는 설계 의도가 담겨 있다. 여기서 아이템 4의 제목의 의미가 나타난다. 설계 의도대로 인스턴스화를 막으려면, private 생성자를 선언하라는 것이다. 생성자를 선언하지 않으면, 기본 생성자가 컴파일 타임에 생성되기 때문이다. Private로 선언하여도 클래스 내부에서는 접근이 가능하기에 생성자 호출 시 Assertion Error 예외를 방생시켜 실수를 방지 할 수 있다. 또한 상속 관계에서 하위타입 .. 2023. 1. 9.
[Item 3] private 생성자나 열거 타입으로 싱글턴임을 보증하라 싱글턴은 인스턴스를 오직 하나만 생성하여 재사용하는 클래스이며 무상태, 유일 객체이다. 인터페이스 정의 없이 클래스를 싱글턴으로 만들면 유일 객체이므로 비용 등이 고려 될 경우 테스트가 불가피해진다. 따라서, 인터페이스 정의 및 구현을 통해 Mock 객체 구현을 통해 테스트를 진행해야한다. mock 테스트 방식이 궁금하다면 하단 github 링크의 mock_test 예제 코드를 참고 바란다. 싱글턴 방식에는 필드, 정적 팩터리, 열거 타입 3가지로 볼 수 있다. 필드 방식 private 기본 생성자를 만들어 놓았기에 필드를 초기화 할 때 한번 호출되어 하나뿐임이 보장된다. 또한 API를 통해 싱글턴 클래스 임을 명확하게 드러낼 수 있고 방식이 간결하다. public class Person { public.. 2023. 1. 7.
[Item 2] 생성자에 매개변수가 많다면 빌더를 고려하라 필수가 아닌 선택적인 매개변수가 많을때 정적 팩터리와 생성자로 대응하기 쉽지 않다는 점이다. 점층적 생성자 패턴 - 선택 값을 하나씩 추가하여 생성자를 점층적으로 만드는 패턴이다. 매개변수의 개수나 타입이 일치하지 않을 경우 컴파일 오류를 통해 누락된 값을 확인할 수 있는 안전성을 가지고 있다. 그러나, 적당한 개수의 매개변수에 대한 점층적 생성자 패턴은 괜찮아 보일지 몰라도 점점 많아지는 생성자로 클래스 코드의 추가 수정 삭제등 유지보수에 대한 불편함이 있다. 또한 각 생성자의 의미, 어떠한 매개변수가 들어가야 하는지에 대한 가독성이 떨어진다.. public class Jwt { private static final String SECRET_KEY = "1234"; // JWT Secret Key pr.. 2023. 1. 7.
[Item 1] 생성자 대신 정적 팩터리 메서드를 고려하라 정적 팩터리 메서드란? 클래스 타입의 인스턴스 생성 방식에는 new 연산자를 통한 생성자 호출 방법 대신 정적 팩터리 메서드를 제공할 수 있다. 정적 팩터리 메서드의 장점이 있지만 단점 또한 존재한다. 장점 1. 이름을 가질수 있다. 널리 사용되는 네이밍 컨벤션이 존재하며 자유로운 이름 지정을 통해 생성자에 비해 명확하다. 생성자의 경우 클래스와 동일한 이름과 매개변수의 타입과 개수의 차이를 두어 다양하게 제공 가능하나 각 생성자에 대한 설명 없이는 파악하는데 어려움이 있다. public class Pros1 { private String name; // private 생성자 private Pros1(String name) { this.name = name; } public static Pros1 of(.. 2023. 1. 7.