생성자를 통해 초기화 할 때, 새로운 객체로 감싸서 복사해주는 방법입니다. 외부와 내부에서 주소값을 공유하는 인스턴스의 관계를 끊어주기 위함입니다. (예를 들어 외부에서 add했는데, 내부에 add가 반영되는 경우) public School(Student[] students) { this.school = new ArrayList(students); } 방어적 복사 이용 만약 생성자에서 유효성 검증이 필요하다고 합시다. 일반적으로는 아래와 같이 넘어온 값을 검증하고 객체 내부변수에 검증된 값을 할당해주는 순서가 맞다고 생각할 수 있습니다. public Period(Date start, Date end) { if (validation(start, end)) { throw new IllegalArgumentE..
메서드와 생성자 대부분은 입력 매개변수의 값이 특정 조건을 만족하기를 바랍니다. 예컨대 인덱스 값은 음수이면 안 되며, 객체 참조는 null이 아니어야 하는 식입니다. 이런 제약은 반드시 문서화해야 하며 메서드 몸체가 시작되기 전에 검사해야 합니다. 이는 "오류는 가능한 한 빨리 (발생한 곳에서) 잡아야 한다"는 일반 원칙의 한 사례이기도 합니다. 오류를 발생한 즉시 잡지 못하면 해당 오류를 감지하기 어려워지고, 감지하더라도 오류의 발생 지점을 찾기 어려워집니다. 메서드 몸체가 실행되기 전에 매개변수를 확인한다면 잘못된 값이 넘어왔을 때 즉각적이고 깔끔한 방식으로 예외를 던질 수 있습니다. 매개변수 검사를 제대로 하지 못하면 몇 가지 문제가 생길 수 있습니다. 1. 메서드가 수행되는 중간에 모호한 예외를..
주류 언어 중, 동시성 프로그래밍 측면에서 자바는 항상 앞서갔습니다. 처음 릴리스된 1996년부터 스레드, 동기화, wait/notify를 지원했습니다. 자바 5부터는 동시성 컬렉션인 java.util.concurrent 라이브러리와 Executor 프레임워크를 지원했습니다. 자바 7부터는 고성능 병렬 분해 프레임워크인 fork-join 패키지를 추가했습니다. 그리고 자바 8부터는 parallel 메서드만 한 번 호출하면 파이프라인을 병렬 실행할 수 있는 스트림을 지원했습니다. 이처럼 자바로 동시성 프로그램을 작성하기가 점점 쉬워지고는 있지만, 이를 올바르고 빠르게 작성하는 일은 여전히 어려운 작업입니다. 동시성 프로그래밍을 할 때에는 안전성(safety)과 응답 가능(liveness) 상태를 유지하기 ..
원소 시퀀스, 즉 일련의 원소를 반환하는 메서드는 수없이 많습니다. 자바 7까지는 이런 메서드의 반환 타입으로 Collection, Set, List 같은 컬렉션 인터페이스 혹은 Iterable이나 배열을 썼습니다. 이 중 가장 적합한 타입을 선택하기란 그다지 어렵지 않았습니다. 기본은 컬렉션 인터페이스입니다. for-ecah 문에서만 쓰이거나 반환된 원소 시퀀스가 주로 (contains(Object) 같은) 일부 Collection 메서드를 구현할 수 없을 때는 Iterable 인터페이스를 썼습니다. 반환 원소들이 기본 타입이거나 성능에 민감한 상황이라면 배열을 썼습니다. 그런데 자바 8이 스트림이라는 개념을 들고 오면서 이 선택이 아주 복잡한 일이 되어버렸습니다. 원소 시퀀스를 반환할 때는 당연히 스..
스트림은 처음 봐서는 이해하기 어려울 수 있습니다. 원하는 작업을 스트림 파이프라인으로 표현하는 것조차 어려울지 모릅니다. 성공하여 프로그램이 동작하더라도 장점이 무엇인지 쉽게 와 닿지 않을 수도 있습니다. 스트림은 그저 또 하나의 API가 아닌, 함수형 프로그래밍에 기초한 패러다임이기 때문입니다. 스트림이 제공하는 표현력, 속도, (상황에 따라) 병렬성을 얻으려면 API는 물론 이 패러다임까지 함께 받아들여야 합니다. 스트림 패러다임의 핵심은 계산을 일련의 변환으로 재구성하는 부분입니다. 이때 각 변환 단계는 가능한 한 이전 단계의 결과를 받아 처리하는 순수 함수여야 합니다. 순수 함수란 오직 입력만이 결과에 영향을 주는 함수를 말합니다. 다른 가변 상태를 참조하지 않고, 함수 스스로도 다른 상태를 변..
스트림 API는 다량의 데이터 처리 작업(순차or병렬)을 돕고자 자바 8에 추가되었습니다. 자바 8에 추가된 기술 [5] Stream 자바 8에는 다양한 기술들을 살펴보려고 하는데, 그 다섯 번째는 Stream이다. 데이터를 담고 있는 저장소(컬렉션)이 아니다. 연속된 데이터를 처리하는 operation의 모임이라고 생각하면 된다. 스트 kkoon9.tistory.com 이 API가 제공하는 추상 개념 중 핵심은 두 가지입니다. 스트림은 데이터 원소의 유한 혹은 무한 시퀀스를 뜻합니다. 스트림 파이프라인은 이 원소들로 수행하는 연산 단계를 표현하는 개념입니다. 스트림의 원소들은 어디로부터든 올 수 있습니다. 대표적으로는 컬렉션, 배열, 파일, 정규표현식 패턴 매처(matcher), 난수 생성기, 혹은 다..
자바가 람다를 지원하면서 API를 작성하는 모범 사례도 크게 바뀌었습니다. 예컨대 상위 클래스의 기본 메서드를 재정의해 원하는 동작을 구현하는 템플릿 메서드 패턴의 매력이 크게 줄었습니다. 이를 대체하는 현대적인 해법은 같은 효과의 함수 객체를 받는 정적 팩터리나 생성자를 제공하는 것입니다. 이 내용을 일반화해서 말하면 함수 객체를 매개변수로 받는 생성자와 메서드를 더 많이 만들어야 합니다. 이 때 함수형 매개변수 타입을 올바르게 선택해야 합니다. LinkedHashMap을 생각해봅시다. 이 클래스의 protected 메서드인 removeEldestEntry를 재정의하면 캐시로 사용할 수 있습니다. 맵에 새로운 키를 추가하는 put 메서드는 이 메서드를 호출하여 true가 반환되면 맵에서 가장 오래된 원..
람다가 익명 클래스보다 나은 점 중에서 가장 큰 특징은 간결함입니다. 그런데 자바에는 함수 객체를 심지어 람다보다도 더 간결하게 만드는 방법이 있으니, 바로 메서드 참조입니다. 다음 코드는 임의의 키와 Integer 값의 매핑을 관리하는 프로그램의 일부입니다. 이 때 값이 키의 인스턴스 개수로 해석된다면, 이 프로그램은 멀티셋을 구현한 게 됩니다. 이 코드는 키가 맵 안에 없다면 키와 숫자 1을 매핑하고, 이미 있다면 기존 매핑 값을 증가시킵니다. map.merge(key, 1, (count, incr) -> count + incr); 이 코드는 자바 8 때 Map에 추가된 merge 메서드를 사용했습니다. merge 메서드는 키, 값, 함수를 인수로 받으며, 주어진 키가 맵 안에 아직 없다면 주어진 {..
- Total
- Today
- Yesterday
- 디자인패턴
- BOJ
- 이팩티브 자바
- 코테
- Olympiad
- 백준
- Effective Java
- Spring Boot
- 프로그래머스
- 객체지향
- BAEKJOON
- AWS
- 클린 아키텍처
- node.js
- Java
- kotest
- Algorithm
- 알고리즘
- JPA
- Kotlin
- programmers
- 정규표현식
- Spring
- kkoon9
- 디자인 패턴
- 이펙티브 자바
- C++
- 테라폼
- 클린 코드
- MSA
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |