전체 글
-
[Effective Java] 박싱된 기본 타입보다는 기본 타입을 사용하라Java 2023. 2. 3. 10:29
자바의 데이터 타입은 크게 두 가지로 나눌 수 있다. int, double, boolean 같은 기본 타입과 String, List 같은 참조 타입이다. 그리고 각각의 기본 타입에는 대응하는 참조 타입이 하나씩 있으며, 이를 박싱된 기본 타입이라고 한다. int, double, boolean에 대응하는 방식된 기본 타입은 Integer, Double, Boolean 이다. 기본 타입과 박싱된 기본 타입 사이에는 분명한 차이가 있으니 어떤 타입을 사용하는지는 상당히 중요하다. 주의해서 선택해야 한다. 기본 타입과 박싱된 기본 타입의 주된 차이 1. 기본 타입은 값만 가지고 있으나, 박싱된 기본 타입은 값에 더해 식별성(identity)이란 속성을 갖는다. 달리 말하면 방식된 기본 타입의 두 인스턴스는 값이..
-
[Effective Java] 정확한 답이 필요하다면 float과 double은 피하라Java 2023. 2. 3. 10:29
float과 double 타입은 과학과 공학 계산용으로 설계되었다. 이진 부동소수점 연산에 쓰이며, 넓은 범위의 수를 빠르게 정밀한 '근사치'로 계산하도록 세심하게 설계되었다. 따라서 정확한 결과가 필요할 때는 사용하면 안된다. float과 double 타입은 특히 금융 관련 계산과는 맞지 않는다. 예 1) 주머니에 1.03달러가 있었는데 그중 42센트를 썼다고 해보면 남은 돈은 얼마인가? System.out.println(1.03 - 0.42); // 출력: 0.6100000000000001 예 2) 주머니에 1달러가 있었는데 10센트짜리 사탕 9개를 샀다고 해보면 얼마가 남았을까? System.out.println(1.00 - 9 * 0.10); // 출력: 0.0999999999999998 예3) ..
-
[Effective Java] 적시에 방어적 복사본을 만들라Java 2023. 2. 3. 10:28
자바는 안전한 언어다. 네이티브 메서드를 사용하지 않으니, C, C++ 같이 안전하지 않은 언어에서 흔히 보는 버퍼 오버런, 배열 오버런, 와일드 포인터 같은 메모리 충돌 오류에서 안전하다. 자바로 작성한 클래스는 시스템의 다른 부분에서 무슨 짓을 하든 그 불변식이 지켜진다. 불변식을 깨드리는 예시 하지만 아무리 자바라 해도 다른 클래스로부터의 침범을 아무런 노력 없이 다 막을 수 있는 건 아니다. 그러니 클라이언트가 여러분의 불변식을 깨뜨리려 혈안이 되어 있다고 가정하고 방어적으로 프로그래밍해야 한다. (평범한 프로그래머도 순전히 실수로 여러분의 클래스를 오작동하게 만들 수 있다.) 어떤 객체든 그 객체의 허락 없이는 외부에서 내부를 수정하는 일은 불가능 하지만, 주의를 기울이지 않으면 자기도 모르게 ..
-
[Effective Java] 매개변수가 유효한지 검사하라Java 2023. 2. 3. 10:27
매개변수가 유효한지 검사하라 메서드와 생성자 대부분은 입력 매개변수의 값이 특정 조건을 만족하기를 바란다. 인덱스 값은 음수이면 안 되며, 객체 참조는 null이 아니어야 하는 식이다. 이런 제약은 반드시 문서화해야 하며 메서드 몸체가 시작되기 전에 검사해야 한다. 이는 "오류는 가능한 한 빨리 (발생한 곳에서) 잡아야 한다"는 일반 원칙의 한 사례이기도 하다. 메서드 몸체가 실행되기 전에 매개변수를 확인한다면 잘못된 값이 넘어왔을 때 즉각적이고 깔끔한 방식으로 예외를 던질 수 있다. 매개변수 검사를 제대로 하지 못하면 생기는 문제 메서드가 수행되는 중간에 모호한 예외를 던지며 실패할 수 있다. 더 나쁜 상황은 메서드가 잘 수행되지만 잘못된 결과를 반환할 때다. 한층 더 나쁜 상황은 메서드는 문제없이 수..
-
[Effective Java] 스트림 병렬화는 주의해서 적용하라Java 2023. 2. 3. 10:26
자바는 동시성 프로그래밍 측면에서 항상 앞서갔다. 처음 릴리즈된 1996년부터 스레드, 동기화, wait/notify를 지원했다. 자바 5부터는 동시성 컬렉션인 java.util.concurrent 라이브러리와 실행자(Executor) 프레임워크를 지원했다. 자바 7부터는 고성능 병렬 분해 프레임워크인 포크-조인(fork-join) 패키지를 추가했다. 자바 8부터는 parallel 메서드만 한 번 호출하면 파이프라인을 병렬 실행할 수 있는 스트림을 지원했다. 이처럼 자바로 동시성 프로그램을 작성하기가 점점 쉬워지고는 있지만, 이를 올바르고 빠르게 작성하는 일은 여전히 어려운 작업이다. 동시성 프로그래밍을 할 때는 안전성과 응답 가능 상태를 유지하기위해 애써야 한다. 파이프라인 병렬화가 불가능한 경우 예)..
-
[Effective Java] 반환 타입으로는 스트림보다 컬렉션이 낫다Java 2023. 2. 3. 10:25
원소 시퀀스, 즉 일련의 원소를 반환하는 메서드는 수없이 많다. 자바 7까지는 이런 메서드의 반환 타입으로 Collection, Set, List 같은 컬렉션 인터페이스, 혹은 Iterable이나 배열을 썼다. 이 중 가장 적합한 타입을 선택하기란 그다지 어렵지 않았다. for-each 문에서만 쓰이거나 반환된 원소 시퀀스가 일부 Collection 메서드를 구현할 수 없을 때는 Iterable 인터페이스를 썼다. 반환 원소들이 기본 타입이거나 성능에 민감한 상황이라면 배열을 썼다. 스트림은 반복을 지원하지 않는다. 그런데 자바 8이 스트림이라는 개념을 들고 오면서 이 선택이 아주 복잡한 일이 되었다. 스트림은 반복(iteration)을 지원하지 않는다. 따라서 스트림과 반복을 알맞게 조합해야 좋은 코드..
-
[Effective Java] 스트림에서는 부작용 없는 함수를 사용하라Java 2023. 2. 3. 10:24
스트림은 처음 봐서는 이해하기 어려울 수 있다. 원하는 작업을 스트림 파이프라인으로 표현하는 것조차 어려울지 모른다. 성공하여 프로그램이 동작하더라도 장점이 무엇인지 쉽게 와 닿지 않을 수도 있다. 단순 API가 아닌 함수형 프로그래밍에 기초한 패러다임이기 때문이다. 스트림 패러담의 핵심은 계산을 일련의 변환으로 재구성하는 부분이다. 이때 각 변환 단계는 가능한 한 이전 단계의 결과를 받아 처리하는 순수 함수여야 한다. 순수 함수란 오직 입력만이 결과에 영향을 주는 함수를 말한다. 다른 가변 상태를 참조하지 않고, 함수 스스로도 다른 상태를 변경하지 않는다. 이렇게 하려면 스트림 연산에 건네는 함수 객체는 모두 부작용이 없어야 한다. 안좋은 예시 다음은 주위에서 종종 볼 수 있는 스트림 코드로, 텍스트 ..
-
[Effective Java] 스트림은 주의해서 사용하라Java 2023. 2. 2. 11:08
스트림 API는 다량의 데이터 처리 작업(순차적이든 병렬적이든)을 돕고자 자바 8에 추가되었다. 이 API가 제공하는 추상 개념 중 핵심은 두 가지다. 스트림은 데이터 원소의 유한 혹은 무한 시퀀스를 뜻한다. 스트림 파이프라인은 이 원소들로 수행하는 연산 단계를 표현하는 개념이다. 스트림 원소들은 어디로부터든 올 수 있다. 대표적으로는 아래와 같은 것들이 있다. 컬렉션 배열 파일 정규표현식 난수 생성기 다른 스트림 스트림 안의 데이터 원소들은 객체 참조나 기본 타입(int, long, double)을 지원한다. Stream : 객체 참조타입에 대한 Stream IntStream: int 타입에 대한 Stream LongStream: long 타입에 대한 Stream DoubleStrema: double ..