모던 자바 Modern JAVA 책 정리 1챕터
[ 챕터 - 1 ] 자바 8,9,10,11 : 무슨 일이 일어나고 있는가?
서론 : 자바의 변화를 우리가 눈여겨봐야 하는 이유는?
- 변화해서 살아남거나, 그대로 머물면 사라지게된다.
- 자바는 새로운 기능과 더불어 계속 발전 중
- 2018년 3월 자바 10 릴리즈
- 2019년 9월 자바 11 릴리즈
1.1 역사의 흐름은 무엇인가 ?
- 자바8 : 가장 크고 획기적인 변화.
- 멀티코어 CPU 대중화와 같은 하드웨어적인 변화도 자바 8에 영향을 미쳤다.
- 지금까지 대부분의 자바 프로그램은 코어 중 하나만을 사용했다 ( 즉, 나머지 코어는 유휴 idle 상태로 두거나, 운영체제나 바이러스 검사 프로그램과 프로세스 파워를 나눠서 사용.)
- 병렬 실행 환경을 쉽게 관리하고 에러가 덜 발생하는 방향으로 진화 ( 자바 8이 등장하기 이전에 나머지 코어를 사용하려면)
자바8 새로운 규칙 :
자바8 특징 : 1) 간결한 코드, 2) 멀티코어 프로세서의 쉬운 활용. 이 2가지 요구사항을 기반으로 함.
-- 스트림API
-- 메서드에 코드를 전달하는 기법
-- 인터페이스의 디폴트 메서드
스트림 API :
- 병렬 연산 ( 데이터베이스 질의 언어에서 표현식 처리하는 것 처럼 )
- 사용하지 않아도 된다. ( 훨씬 비싼 키워드 synchronized. 에러를 자주 일으키며 멀티코어 cpu를 이용하는 것보다 비용이 훨씬 비싼. )
1.2 왜 아직도 자바는 변화하는가 ?
자바가 거듭 변화하는 이유 : 프로그래밍 언어가 마치 생태계와 같다고 표현.
생태계와 닮은 점 :
-> 새로운 언어 등장 후 진화하지 않은 기존 언어는 사장 되는 것.
-> 특정 분야에서 장점을 가진 언어는 경쟁 관계에 있는 다른 언어를 도태시킴.
--> 기존 개발자들은 새로운 기능 하나 때문에 익숙한 언어에서 새로운 언어로 툴과 그 생태계를 바꾸는 것이 쉽지 않은 일이지만,
--> 새롭게 프로그래밍을 배우는 사람은 자연스럽게 새로운 언어를 선택하게되어 새로운 언어의 새로운 기능을 배우는데, 이 때 기존 언어가 재빠르게 진화하지 않는다면 기존 언어는 도태된다. (ex. 에이다, 알골, 코볼, 파스칼, 델파이, 스노볼 등의 언어 )
-> 자바는 1995년 첫 베타 버전 공개 이후, 커다란 생태계를 성공적으로 자리를 지켰는데 그 이유는 1.2.1에서.
1.3 함수
- 자바8에서 함수를 새로운 값의 형식으로 추가함. 이유는 스트림과 연계될 수 있어야 해서. ( 멀티코어, 병렬 프로그래밍을 활용할 수 있는 )
- 메서드와 클래스는 그 자체로 값이 될 수 없는 이급 시민이었는데, 이제 일급시민으로 만든다면 아주 유용하다.
1.3.1
- 프로그래머가 활용할 수 있는 도구가 다양해진다. 메서드를 일급값으로 사용하면.
메서드 참조 method reference :
- 기존에 객체 참조 object reference (new 로 객체 참조를 생성)를 생성해서 객체를 이리저리 주고받았던 것처럼 자바 8에서는 File::isHidden을 이용해서 메서드 참조를 만들어 전달 할 수 있게 되었다.
람다 : 익명함수
- 직접 메서드를 정의할 수도 있지만, 이용할 수 있는 편리한 클래스나 메서드가 없을 때 새로운 람다 문법을 이용하면 더 간결하게 코드를 구현할 수 있다.
- 람다 문법 형식으로 구현된 프로그램을 함수형 프로그래밍, 즉 '함수를 일급값으로 넘겨주는 프로그램을 구현 한다' 라고 한다.
1.3.2 코드 넘겨주기 : 예제
- 예제의 핵심은 자바 8에서는 메서드를 전달 할 수 있다는 사실.
- 프레디케이트 (predicate) : 수학에서는 인수로 값을 바당 true나 false를 바나환하는 함수를 프레디케이트라고 한다.
1.3.3 메서드 전달에서 람다로.
- 한두번만 사용할 메서드를 매번 정의하는 것은 귀찮은 일. 자바 8에서는 이 문제도 간단히 해결.
- 한 번만 사용할 메서드는 따로 정의를 구현할 필요가 없다.
- 하지만 람다가 몇 줄 이상으로 길어진다면 익명 람다 보다는 코드가 수행하는 일을 잘 설명하는 이름을 가진 메서드를 정의하고 메서드 참조를 활용하는 것이 바람직하다.
- 라이브러리 메서드 filter를 이용하면 filterApples 메서드를 구현할 필요가 없다.
1.4 스트림.
- 컬렉션 API와 스트림 API의 반복 차이점
컬렉션 API, 반복 과정을 직접 처리. for-each 루프를 이용해서 각 요소를 반복하면서 작업을 수행. 외부반복 (external iteration) 이라고 한다.
스트림 API를 이용하면 루프를 신경 쓸 필요가 없다. 라이브러리 내부에서 모든 데이터가 처리된다. 내부 반복(internal ieteeration) 이라고 한다.
- 스트림 API로 2가지 문제 해결
1) 컬렉션을 처리하면서 발생하는 모호함과 반복적인 코드 문제.
2) 멀티코어 활용 어려움.
- 스트림은 스트림 내의 요소를 쉽게 병렬로 처리할 수 있는 환경을 제공한다는 것이 핵심.
- 컬렉션을 필터링할 수 있는 가장 빠른 방법은 컬렉션을 스트림으로 바꾸고, 병렬로 처리한 다음에, 리스트로 다시 복원하는 것.
1.5 디폴트 메서드와 자바 모듈
- 자바 9의 모듈 시스템은 모듈을 정의 하는 문법 제공. 모듈 정의 할 수 있게 됨.
- 모듈 덕분에 JAR 같은 컴포넌트에 구조를 적용.
디폴트 메서드 :
- 특정 프로그램을 구현하는 데 도움을 주는 기능이 아니라 미래에 프로그램이 쉽게 변화할 수 있는 환경을 제공하는 기능.
- 자바8 버전에서는 인터페이스를 쉽게 바꿀 수 있음.
- 우리는 딜레마에 빠진다. 어떻게 기존의 구현을 고치지 않고도 이미 공개된 인터페이스를 변경 할 수 있을까?
- 결정적으로 자바8은 구현 클래스에서 구현하지 않아도 되는 메서드를 인터페이스에 추가할 수 있는 기능을 제공.
- 메서드 본문은 클래스 구현이 아니라 인터페이스의 일부로 포함된다. 그래서 이를 디폴트 메서드라고 부른다.
- 디폴트 메서드를 이용하면 기존의 코드를 건드리지 않고도 원래의 인터페이스 설계를 자윫게 확장할 수 있다.
- 자바 8에서는 인터페이스 규격명세에 default라는 새로운 키워드를 지원한다.
1.6 함수형 프로그래밍에서 가져온 다른 유용한 아이디어.
2가지 핵심적인 아이디어.
- 메서드와 람다를 일급값으로 사용하는 것.
- 가변 공유 상태가 없는 병렬 실행을 이용해서 효율적이고 안전하게 함수나 메서드를 호출할 수 있다는 것.
- 스트림 API는 이 2가지 아이디어를 모두 활용한다.
1.7 마치며
- 언어 생태계의 모든 언어는 변화해서 살아남거나 그대로 머물면서 사라지게 된다.
- 자바 8은 프로그램을 더 효과적, 간결하게 구현 할 수 있는 새로운 개념과 기능(메소드 전달, 람다 등 ) 제공.
- 기존 자바 프로그래밍으로는 멀티코어 프로세서를 온전히 활용하기 어렵다.
- 함수는 일급값. 메서드를 어떻게 함수형값으로 념겨주는지, 익명 함수(람다)를 어떻게 구현하는지 기억하기.
- 자바 8의 스트림 개념 중 일부는 컬렉션에서 가져온 것. 스트림과 컬렉션을 적절하게 활용하면 스트림의 인수를 병렬로 처리할 수 있으며 더 가독성 좋은 코드 개발 가능.
- 기존 자바 기능으로는 대규모 컴포넌트 기반 프로그래밍 그리고 진화하는 시스템의 인터페이스를 적절하게 대응하기 어려웠다. 자바 9에서는 모듈을 이용해 시스템의 구조를 만들 수 있고, 디폴트 메소드를 이용해 기존 인터페이스를 구현하는 클래스를 바꾸지 않고도 인터페이스를 변경 가능 했음.