본문 바로가기

Language/Java33

이펙티브 자바 - 종료자 사용을 피하라 - 이 글은 Effective Java 를 기반으로 작성되었습니다. - 종료자 Java 의 종료자(finalize)는 예측 불가능하며 대체로 위험하고 일반적인 상황에서는 불필요 하다. C++ 소멸자의 경우 메모리 반환과 자원반환의 일반적인 수단이지만, Java 의 경우 GC가 메모리를 정리해주고 자원반환과 같은 경우에도 try-finally 구문을 사용하기 때문에 정말 특수한 상황이 아니면 종료자를 사용할 필요가 없다. - 종료자의 단점 종료자의 첫번째 단점은 예측이 되지 않는다는것이다. 즉시 실행이 보장되지 않는데 모든 참조가 사라지고 난 후 종료자가 실행되기까지에는 어느정도 간격이 존재한다. 그래서 특히 time-critical 한 작업에는 절대로 종료자는 사용하면 안된다. 만약 file close .. 2021. 9. 22.
이펙티브 자바 - 유효기간이 지난 객체 참조 - 이 글은 Effective Java 를 기반으로 작성되었습니다. - Java 의 GC C, C++ 처럼 메모리 관리를 손수 하다가 Java 를 처음 사용해보면 편리함을 느끼게 된다. 메모리 관리를 손수하지 않아도 GC 가 알아서 해주기 때문이다. 그렇다며 메모리 관리는 전혀 신경쓰지 않아도 되는거 아닌가 라고 착각하게 될 수 있는데 이는 잘못된 생각이다. - 유효기간이 지난 객체 참조 자료구조를 젤 처음 접할 때 보통은 Queue 나 Stack 을 구현하게 된다. Stack 의 경우 배열을 선언해놓고 push, pop 연산시 index 를 증감시킨다. public class SimpleStack { private Object[] elements; private static final int DEFAU.. 2021. 9. 19.
이펙티브 자바 - 불필요한 객체 생성 - 이 글은 Effective Java 를 기반으로 작성되었습니다. - 불필요한 객체 생성 기능이 동일한 객체가 있다면 새로 생성하지 않고 재사용을 하는 편이 좋다. 특히 변경 불가능한 immutable 객체의 경우 값을 변경하지 않기 때문에 언제나 재사용이 가능하다. String test1 = "test1"; String test2 = "test1"; String test3 = new String("test1"); String test4 = new String("test1"); 위의 코드에서 모두 같은 test1 이라는 문자열을 생성하지만 test1 과 test2 는 리터럴 형식으로, test3 과 test4 는 new 를 이용해서 String 객체를 생성했다. test1 과 test2 는 JVM 내에.. 2021. 9. 18.
이펙티브 자바 - 싱글턴 패턴 - 이 글은 Effective Java 를 기반으로 작성되었습니다. - 싱글턴 싱글턴은 객체를 하나만 만들 수 있는 클래스이다. 1.5 이전 버전의 JDK 에서는 2 가지 방법으로 싱글턴을 구현할 수 있다. 하나는 정적 멤버를 선언하는 것이고 다른 하나는 정적 팩토리 메소드를 이용하는 것이다. 이 방법으로 어떻게 싱글턴을 구현할 수 있는지 살펴보자. 2 가지 방법은 구현방법이 다르지만 공통점이 있는데 생성자가 private 여야 한다는 것이다. 생성자를 private 로 써야한다니 뭔가 있어 보이지만 생각해보면 객체가 하나만 존재하려면 자기자신 외에 생성자를 호출하면 안되므로 당연한것이다. - 정적 멤버 첫번째 방법은 정적 멤버 final (static final) 멤버를 초기화하고 이를 외부에 공개하는.. 2021. 9. 18.
이펙티브 자바 - Builder 패턴 - 이 글은 Effective Java 를 기반으로 작성되었습니다. - Builder 패턴 정적 팩토리 메소드나 생성자는 선택적 인자가 많을 때 사용하기가 난감하다. 빌더 패턴은 이런 문제를 해결하기 위해 사용하는 패턴인데 예를 통해서 알아보도록 하자. - 점층적 생성자 패턴 만약 성분표에 필수 항목으로 총 제공량, 1회 제공량이 있고, 선택적 항목에는 칼로리, 지방, 나트륨, 탄수화물이 있다고 가정해보자. 만약 필수적인 항목과 선택적인 항목으로도 생성자를 사용할 수 있게 하려면 생성자를 여러 개 정의 해야 한다. 점층적 생성자 패턴이라고 불리우는 방식을 통해 이 문제를 해결하려고 하면 코드는 아래와 같이 될 것이다. public class NutritionFactsTelescoping { private.. 2021. 9. 16.
이펙티브 자바 - 정적 팩토리 메소드 - 이 글은 Effective Java 를 기반으로 작성되었습니다. - 정적 팩토리 메소드 객체를 생성하는 일반적인 방법은 public 생성자를 이용하는것이다. 하지만 정적 팩토리 메소드를 이용할 수도 있다. Boolean 의 valueOf 메소드는 기본 타입의 boolean 을 Boolean 객체 참조로 변환한다. public static Boolean valueOf(boolean b) { return b ? Boolean.TRUE : Boolean.FALSE; } 흔히 정적 팩토리 메소드를 디자인 패턴의 팩토리 메소드와 혼동한다. 디자인 패턴의 팩토리 메소드는 하나의 환경변수나 다른 변수를 (팩토리)만 변경하면 제품군들도 일괄적으로 변경되어 생성되도록 하는 패턴이다. 예를 들어 객체 RadioA1과 .. 2021. 9. 5.
[Java 8] 날짜 API - 2 - 출처: https://www.oracle.com/technical-resources/articles/java/jf14-date-time.html - 출처: 자바 8 인 액션 - Truncation 신규 API 는 날짜, 시간, 날짜 및 시간을 표현하는 타입을 제공하여 정밀한 시간을 지원하지만, 이것보다 더 세밀하게 정의된 정밀도의 개념을 지원한다. truncatedTo 메소드는 이런 경우에 사용하는데, DB의 truncate 와 비슷하게 해당 필드에 대한 값을 비운다. LocalDateTime timePoint = LocalDateTime.now(); LocalDateTime truncatedTime = timePoint.truncatedTo(ChronoUnit.SECONDS); System.out... 2021. 2. 11.
[Java 8] 날짜 API - 1 - 출처: https://www.oracle.com/java/technologies/jf14-date-time.html - 왜 새로운 날짜 API가 필요한가? 자바8 이전에는 날짜와 시간에 대한 기능 지원이 부족했다. 예를 들어 java.util.Date 와 SimplteDateFormatter 와 같은 클래스들은 스레드-세이프 하지 않아서 사용자에게 잠재적인 병렬성 이슈를 불러일으킬 가능성이 있었다. 또한 날짜와 시간 관련 클래스중 일부는 API 디자인 측면에서 부족한 부분이 있었다. 예를 들면 java.util.Date는 1900년 부터 시작하고, 달의 인덱스는 0부터 시작하며, 일의 인덱스는 1부터 시작하여 직관적이지 않은 부분이 있다. 이런 이슈들과 다른 문제점들은 Joda-Time 같은 제 3의.. 2021. 2. 11.
[Java 8] CompletableFuture - 4 (종료조건) - 출처: 자바 8 in action - CompletableFuture 종료 앞서 작성한 코드들에서 원격 서비스를 흉내내기 위해 1초 sleep을 주었지만 사실 실제 상황에서는 네트워크 상황이나 다른 변수등 어떤일이 일어날지 알 수 없다. 그래서 원격 서비스를 사용할 때 더 실제와 같은 상황을 부여하기 위해 랜덤하게 sleep을 할당해보자. getTicketPrice 메소드에 sleep 부분을 아래 코드로 변경하자. int delay = 500 + random.nextInt(2000); try { Thread.sleep(delay); } catch (InterruptedException e) { throw new RuntimeException(e); } 앞선 코드는 모든 가격이 조회될때까지 기다렸지만 .. 2021. 2. 11.
[Java 8] CompletableFuture - 3 (비동기 파이프라인) - 출처: 자바 8 in action - 할인 계산 서비스 추가 CompletableFuture-2 코드를 이용하여 할인을 적용한 가격을 구하는 서비스를 작성해보자. 앞에서 getPrice는 가격 하나만을 반환했는데 from::to::price 형태의 :: 구분자 반환한다고 가정하자. 아래는 반환부가 새로 정의된 Airline class이다. public class Airline { public Future getTicketPriceAsyncViaSupplyAsync(String from, String to){ return CompletableFuture.supplyAsync(() -> { validateTicket(from, to); return getTicketPrice(from, to); }); }.. 2021. 2. 11.