목록Study/Java (17)
전공공부
관리자 페이지 운영 중 Jackson Mapper 관련한 라이브러리 이전 버전일 경우 JDK8의 LocalDateTime을 제대로 파싱해서 가져오지 못하는 오류가 생겼다. 이는, 단순히 JacksonMapper 버전을 상승시켜서 해결 할 수 있다. 하지만, 리스크가 크고 이에 따라서 아래의 방법을 적용했다. JDK 8 이상 부터 LocalDateTime의 직렬화 바이트 스트림을 제대로 파싱하기 위한 의존성 주입 com.fasterxml.jackson.datatype jackson-datatype-jsr310 @Bean 객체로 등록한 ObjectMapper에 아래와 같이 자바 타임 모듈에 역직렬화시 쓰일 데이터 포메터 지정하여서 역직렬화시 DTO 파싱 오류를 잡음 @Bean ObjectMapper mapp..

readObject는 생성자 아이템 50에서 가변인 Date 클래스를 사용하기 때문에 방어적 복사를 진행하여 불변식을 지켰던 클래스가 기억이 날 것이다. // 방어적 복사를 사용하는 불변 클래스 public final class Period { private final Date start; private final Date end; /** * @param start 시작 시각 * @param end 종료 시각; 시작 시각보다 뒤여야 한다. * @throws IllegalArgumentException 시작 시각이 종료 시각보다 늦을 때 발생한다. * @throws NullPointerException start나 end가 null이면 발행한다. */ public Period(Date start, Date..

OS Thread Scheduler 여러 스레드가 실행 중이면 운영체제의 스레드 스케줄러가 어떤 스레드를 얼마나 오래 실행할지 정한다. 정상적인 운영체제라면 이 작업을 공정하게 수행하지만 구체적인 스케줄링 정책은 운영체제마다 다를 수 있다. 따라서 잘 작성된 프로그램이라면 이 정책에 좌지우지돼서는 안된다. (OS에 따라서 성능이 달라지면 안됌.) 정확성이나 성능이 스레드 스케줄러에 따라 달라지는 프로그램이라면 다른 플랫폼에 이식하기 어렵다. 견고하고 이식성이 좋은 프로그램을 만드는 법 해결방법 : 실행가능한 스레드의 평균적인 수를 프로세서 수보다 지나치게 많아지지 않도록 설계해야 한다. 그러면, 실행가능한 스레드의 수를 적게 유지하는 방법은 없을까? 각 스레드가 일을 마치면 다음 일거리가 생길때 까지 대..

과도한 동기화의 문제 충분하지 못한 동기화도 문제이지만 과도한 동기화도 문제다. 성능을 떨어뜨리고 교착상태(Deadlock)에 빠질 수 있으며 심지어 응답 불가나 잘못된 결과를 계산해내는 안전 실패(safety failure)를 일으킬 수 있다. 응답 불가와 안전 실패를 피하려면 동기화 메서드와 동기화 블록 안에서는 제어를 절대로 클라이언트에 양도하면 안 된다. 1. 동기화된 블록 안에서는 재정의 가능한 메서드 2. 클라이언트가 넘겨준 함수 객체를 동기화 메서드 내부에서 호출 무슨 일을 할지 모르기 때문에 예외를 발생시키거나, 교착상태를 만들거나, 데이터를 훼손할 수 있다. 위와 같은 메서드를 외계인 메서드(alien method)라고 한다. 외계인 메서드 예시 코드 동기화 블럭 내부에서 외계인 코드를 ..
검사 예외의 문서화 검사 예외는 (RuntimeException 및 Error를 제외한 예외들) 항상 따로따로 선언하고, 각 예외가 발생하는 상황을 자바독의 @throws 태그를 통하여 정확히 문서화하자. 극단적인 예로 메서드가 Exception이나 Throwable을 던진다고 선언해서는 안된다. 이렇게 선언해버리면 API 사용성을 크게 떨어트릴 수 있다. (상세 예외 케이스를 내어주지 못하니 대처가 힘듦) 위 규칙에는 예외가 있는데 바로 main 메서드이다. JVM에서만 호출하므로 Exception을 던져도 무방하다. 비검사 예외의 문서화 비검사 예외도 정성껏 문서화하면 좋다. 프로그래밍을 하면서 나는 프로그래밍 오류들이 비검사예외인데 이러한 상황을 맞딱트릴 수 있다고 API에서 먼저 문서화 해두면 코..

호출하는 쪽에서 복구 할 수 있는 상황이라면 검사 예외를 사용하자 검사 예외를 사용하면 호출자가 그 예외를 catch로 잡아서 처리하거나 더 바깥으로 전파하도록 강제하게 된다. 프로그래밍 오류를 나타낼 때는 런타임 예외를 사용하자 비검사 throwable은 두 가지로 런타임 예외와 에러다. 비검사 예외나 에러는 복구가 불가능한 경우나 더 실행해봐야 득보다는 실이 많은 경우에 사용한다. 여기서, 런타임 예외의 대부분은 단순히 클라이언트가 API 명세를 따르지 않아서 일어나는 예외이다. 위 상황에 대한 예는 ArrayIndexOutOfBoundsException 으로 쉽게 설명이 가능하다. 배열의 인덱스는 적어도 0에서 시작하고 '배열 길이 -1' 사이여야 한다. 하지만, 이때 ArrayIndexOutOfB..

컬랙션이 비었을 때 null을 반환하는 메서드를 보자 private final List cheesesInStock = ...; /** * @return 매장 안의 모든 치즈 목록을 반환한다. * 단, 재고가 하나도 없다면 null을 반환한다. */ public List getCheeses() { return cheesesInStock.isEmtpy() ? null : new ArrayList(cheesesInStock); } 해당 코드의 문제점은 클라이언트가 null 상황을 처리하는 코드를 추가로 작성해야 한다. List cheeses = shop.getCheeses(); if(cheeses != null && cheeses.contains(Cheese.STILTON)) System.out.println..

자바8 이전의 반환 타입 - 자바 7까지는 일련의 원소를 반환하는 메서드를 사용 할 때 반환 타입으로 Collection, Set, List 같은 컬렉션 인터페이스 또는 Iterable이나 배열을 썼다. - for-each 문에서만 쓰이거나, 반환된 원소 시퀸스가 일부Collection 메서드를 구현할 수 없을 때는 Iterable 인터페이스를 썼다. (contains(Obejct) 같은 경우) - 반환 원소들이 기본 타입이거나 성능에 민감한 상황이라면 배열을 썼다. 자바8 이후의 반환 타입 - 자바8에서 스트림이 등장하면서 반환 타입의 선택이 복잡한 일이 되었다. Steam과 Iterable - 원소 시퀸스를 반환할 때는 당연히 스트림을 사용해야한다. 하지만, 스트림은 반복(iteration)을 지원하..