java
Item 02 + Example
Item 02 + Example 생성자에 매개변수가 많다면 빌더를 고려하라 생성자에 매개변수가 아주 많고, 대부분의 경우 각 필드의 기본 값이 있는 경우, 점층적 생성자 패턴 사용 가능 이 패턴은 사용이 불가능한 것은 아니나, 매개변수가 많아질 수록 코드를 작성하고 읽기 어려움 생성자에 각 필드의 기본값을 세팅하고 이후 setter를 사용하는 방법 자바빈즈 패턴도 존재 이 패턴은 객체 하나를 만들려면 setter 메서드를 여러 개 호출해야 함 또한 객체가 완전히 생성되기 전에 일관성이 깨진 상태로 존재할 수 있다는 점이 문제 또한 클래스를 immutable로 만들 수 없음 이런 방법들의 대안으로 나온 것이 빌더 패턴 필수 매개변수만으로 생성자를 호출해 빌더 객체를 획득 이후 빌더 객체가 제공하는 메서드들을 호출해서 매개변수를 설정 마지막으로 매개변수가 없는 build 메서드를 호출해서 목표한 (불변) 객체를 획득 읽고 쓰기 쉬우며, 유연하게 여러 타입의 객체를 만들 수 있음 계층적 클래스에서 계층적으로 설계된 클래스에서 각 계층의 클래스에 관련된 빌더를 멤버로 정의 추상 클래스는 추상 빌더를, 구현하는 클래스에서는 실제로 구현된 빌더를 작성하면 됨 Simulated self-type 이라는 방법을 통해 하위 클래스에서는 형 변환 없이 메서드 연쇄를 지원함 self 타입이 없는 자바를 위한 방법.
read morejava
Item 01 + Example
Item 01 + Example 생성자 대신 정적 팩터리 메서드를 고려하라 인스턴스를 얻기 위한 가장 고전적인 방법은 public 생성자 그러나 정적 팩터리 메서드라는 인스턴스를 반환하는 단순한 정적 메서드를 이용하는 방법이 있음 이 방법은 여러 장단점이 존재 장점 메서드기 때문에 이름을 가질 수 있음 인스턴스를 생성할 때 의미를 명확하게 할 수 있음 호출될 때 마다 인스턴스를 새로 생성하지 않아도 될 수 있음 Immutable 클래스의 경우에는 캐싱한 인스턴스를 재활용 가능 반환 타입의 하위 타입 객체를 반환 가능 반환할 객체의 클래스를 선택 가능하므로 엄청난 유연성 제공 자바 8에서 인터페이스가 정적 메서드를 가질 수 있게 되면서 이 이점이 더욱 극대화됨 입력 매개변수에 따라 다른 클래스의 객체 반환 가능 클라이언트는 어떤 클래스의 객체가 반환되는지 알 필요가 없음 반환하는 클래스의의 하위 타입 클래스의 객체이기만 하면 됨 정적 팩토리 메소드를 작성할 시기에, 반환할 객체의 클래스가 없어도 됨 이 부분은 인터페이스를 클라이언트에 넘겨줘도 되기 때문에, 구현을 나중으로 미뤄도 된다는 뜻으로 이해했습니다 단점 정적 팩터리 메서드만 제공하는 경우 상속을 통해 하위 클래스를 만들기가 불가능 상속을 위해서는 public 혹은 protected 생성자가 필요하기 때문 정적 팩터리 메서드를 프로그래머가 찾기 힘듦 생성자와 달리 API에 설명이 명확히 드러나지 않음 API 문서를 잘 쓰고, 메서드 이름도 컨벤션을 따르는 등의 노력이 필요 정적 팩터리 메서드 명명 방식 from: 매개변수 하나를 받아서 해당 타입의 인스턴스를 반환 of: 여러 매개변수를 받아 적합한 타입의 인스턴스를 반환 valueOf: from, of의 자세한 버전 instance / getInstance: 매개변수로 명시한 타입의 인스턴스를 반환 create / newInstance: 매개변수로 명시한 타입의 새로운 인스턴스를 만들어 반환 type / getType: getInstance와 비슷하나, 다른 Type의 인스턴스를 만들 때 사용 type/ newType: newInstance와 비슷하나, 다른 Type의 인스턴스를 새로 만들어 반환할 때 사용 Example 소스 코드
read morejava
참조의 종류
참조의 종류 참조의 종류 참조에는 다음과 같은 여러 종류가 존재함 Strong References Item item = new Item(); 위와 같은 new 를 통해 객체를 생성한 경우 생기는 일반적인 참조 어떤 객체가 강한 참조를 통해 도달할 수 있다면, 해당 객체는 GC의 대상이 아님 참조가 해제되는 경우에만 GC의 대상이 됨 메모리 누수의 원인이 될 수 있음 Weak References WeakReference weakItem = new WeakReference(item); 위와 같이 WeakReference를 통해 생성한 참조 weakItem.get()을 통해 객체를 가져올 수 있음 GC 발생하면, 약한 참조만 있는 객체는 수거됨 짧은 기간동안만 필요한 객체를 사용할 때 유용 캐시 등의 key-value 자료 구조가 필요하면 WeakHashMap을 이용하면 됨 이 경우 key가 GC에 의해 수거되면, 해당 key에 해당하는 value 역시 수거됨 Soft References Weak reference와 비슷하지만, GC가 객체를 덜 수거하는 참조 만약 메모리가 충분하다면, GC가 객체를 수거하지 않음 Weak reference보다 더 캐시에 적합 References https://recordsoflife.
read morejava
Item 4
Item 4 인스턴스화를 막으려거든 private 생성자를 사용해라 정적 메소드와 정적 필드만을 담은 유틸리티 클래스를 만드는 경우가 존재 가능 java.lang.Math 혹은 java.util.Arrays와 같이 primitive type 혹은 배열을 다루는 메서드들을 모아 놓는 클래스 java.util.Collections 처럼 인터페이스를 구현하는 정적 메서드들로 구성된 클래스 final 클래스에 관련된 메서드들을 모아 둔 클래스 이런 유틸리티 클래스에서 생성자를 명시하지 않게 되면, 기본 생성자가 만들어 짐 매개변수를 받지 않는 public 생성자 즉, 인스턴스화를 할 수 있게 됨 추상 클래스로 만든다고 인스턴스화가 막히는 것은 아님 하위 클래스를 만들어서 상속받은 후 인스턴스화를 진행하면 되기 때문 따라서 이렇게 인스턴스화를 막아야 하는 유틸리티 클래스는 private 생성자를 추가하면 됨 참고 사항 private 생성자이므로, 외부에서는 호출할 수 없게 됨 그러나 내부에서 실수로 호출하거나, reflection API 등을 이용한 생성자 호출을 할 수도 있음 이런 경우를 막기 위해 AssertionError를 던져주면, 인스턴스화가 되지 않음 이 경우는 코드가 직관적이지 않으므로 적절한 주석으로 설명해 두는 것도 좋은 방법 또한 private 생성자가 있는 경우 상속이 불가능해짐 하위 클래스는 상위 클래스의 생성자를 호출해야 하므로 class SomeUtilClass { // 인스턴스화 방지를 위해 기본 생성자가 만들어 지는 것을 막는다 private SomeUtilClass() { throw new AssertionError(); } } References 조슈아 블로크 - Effective Java 3/E
read morejava
RuntimeException
RuntimeException RuntimeException 모든 unchecked exception이 상속받아야 하는 예외 반드시 예외 처리를 하지 않아도 됨 실행 중에 입력값이 잘못 들어오는 등 특정 조건을 만족하면 발생됨 대표적인 Runtime Exception 예시 ArrayIndexOutOfBoundsException IllegalArgumentException NullPointerException References https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=mk1126sj&logNo=220976674605 https://nhj12311.tistory.com/204
read morejava
Java Default 접근 제어자
Java Default 접근 제어자 Java Default 접근 제어자 Java의 default 접근 제어자는 클래스 및 클래스 멤버에 대한 접근 제어를 명시하는 키워드 default 접근 제어자는 동일한 패키지 내에 있는 다른 클래스만이 접근 가능하게 함 아무 접근 제어자를 붙이지 않는 경우 기본으로 적용됨 private과 protected의 사이의 은닉 수준 제공 언제 사용하면 좋을까 한 패키지 내에 B라는 클래스가 A라는 클래스를 의존할 수 있음 이 때 B 클래스가 A 클래스의 멤버 변수 값이 필요할 수 있고, 이를 얻기 위해 getter를 사용함 그러나 객체 지향 생활 체조 원칙 등에서는 정보 은닉을 보장하기 위해 getter의 사용을 지양하라고 되어 있음 이런 상황에서 getter 를 쓰되, default 접근 제어자를 사용하는 절충안이 존재 이 경우, 패키지 외부로 getter가 나가는 것이 아니므로, 정보 은닉을 해친다고 보기는 힘들다고 생각 물론 같은 패키지에서도 이 방식이 문제가 될 수 있으므로, 완벽한 정답은 아님.
read morejava
Java 리스트를 배열 대신 사용하는 이유
Java 리스트를 배열 대신 사용하는 이유 Java 리스트를 배열 대신 사용하는 이유 배열은 제네릭을 사용할 수 없고, 정적인 크기를 가짐 반면 리스트(Collection)는 동적인 자료 구조이며, 제네릭을 지원 배열은 Sub 클래스가 Super 클래스의 하위 클래스인 경우, Sub[] 역시 Super[]의 하위 클래스 이런 특성을 공변이라고 하는데, 이는 런타임 때(특히 데이터를 쓸 때) ArrayStoreException등의 예외가 발생할 수 있음 컴파일때 문제를 찾기 어렵다는 점이 존재 다만 런타임때 자신이 담기로 한 원소의 타입을 확인하기 때문에 런타임때 안정적이긴 함 반대로 리스트는 공변이 아님.
read morejava
WebSecurityConfigurerAdapter SecurityFilterChain
WebSecurityConfigurerAdapter SecurityFilterChain WebSecurityConfigurerAdapter Spring Security에서 웹 보안 기능을 담당하는 클래스 이 클래스를 상속받아 configure 메소드에서 사용자 정의 보안 기능을 구현 이 클래스를 상속받는 클래스는 @EnableWebSecurity 어노테이션을 붙여야 함 최신 Spring Security에서는 컴포넌트 기반의 보안 설정을 권장하므로, deprecate 됨 SecurityFilterChain Spring Security에서 최근에 권장하는 보안 관련 bean 기존과 달리 Configuration 클래스에서 SecurityFilterChain을 반환해 Spring Bean으로 등록 WebSecurityCustomizer 역시 등록해야 함 References https://velog.io/@seongwon97/security https://jaehoney.tistory.com/249 https://devlog-wjdrbs96.tistory.com/434
read morejava
JVM Compile Process
JVM Compile Process JVM Compile Process Java 코드를 자바 컴파일러를 통해 자바 바이트코드로 작성 컴파일된 바이트코드(.class 파일)를 JVM의 클래스 로더에게 전달 클래스 로더는 총 3단계로 다음 동작을 수행 로딩: 자바 바이트 코드를 JVM의 runtime data area에 적재함 링킹: 로딩된 클래스 파일을 검증하고, 필요한 메모리를 할당하고, 심볼릭 레퍼런스를 다이렉트 레퍼런스로 변경 초기화: 동시성을 고려해 static 필드를 초기화 및 초기화 메서드 수행 이제 JVM이 클래스 파일을 실행할 수 있게 되었으므로, 실행 엔진이 인터프리터 방식으로 바이트 코드 명령어를 하나씩 실행 인터프리터 방식으로 실행되다가 일정 기준이 넘어가면, JIT 컴파일러가 수행됨 반복되는 바이트 코드를 컴파일해서 native code로 직접 실행 Native code로 변경된 코드는 캐싱해 둠 모든 코드를 JIT 컴파일하는 것은 비효율적이므로, 일정 기준을 넘어갔을 때만 수행됨 References https://steady-snail.
read morejava
Spring WebFlux
Spring WebFlux Spring WebFlux Spring 5에서 추가된 모듈 클라이언트와 서버에서 반응형 스타일의 애플리케이션을 도와줌 비동기 논블로킹 방식으로 메시지를 처리 함수형 스타일로 개발함 장단점 장점 비동기 논블로킹 방식이기 때문에, 트래픽이 많을 수록 MVC에 비해 성능이 좋음 Context switch에 드는 비용을 최소화해서 최소 스레드로 최대 성능을 낼 수 있음 Spring과 통합이 잘 되어 있으며, Netty도 지원함 단점 오류 처리가 복잡 기술적 난이도가 높음 아직 RDBMS에 대한 지원이 부족 MVC의 스레드 모델도 충분히 빠르기 때문에 쓸 이유가 많지 않음 대용량 트래픽을 처리하는 서버가 아닌 이상 큰 성능상 이점이 없음 이런 이유들로 아직 실무에서는 거의 사용되지 않음 References https://devuna.
read more