자바 5의 가장 중요한 신규 기능. 제네릭을 이용해서 기존 컬렉션 프레임워크를 이용했을 때 발생할 수 있는 ClassCastException을 컴파일 시간에 검증할 수 있다. 이러한 컴파일 검증 기능뿐만 아니라 코드에 대한 데이터를 명확하게 해서 가동성을 높으는 결과도 가져옴
for 루프 개선
이전까지는 루프를 실행하기 위한 인덱스 변수를 생성해서 기계적으로 값을 돌리거나 Iterator 인터페이스를 이용하였지만. for each 구문을 사용하면 그러한 번거로움 없이 for 루프를 구현할 수 있다. for each를 사용하기 위해서는 데이터 타임이 명확해야 하는 제약이 있어서 제네릭을 사용하거나 형이 명확한 배열을 이용해야 한다.
컨커런트 API
병렬 프로그래밍 혹은 멀티 스레드 프로그래밍을 위해서는 자바 스레드 구조에 대한 해박한 지식을 기반으로 저 수준의 프로그래밍을 해야 한다. 하지만 컨커런트 API를 이용하면 비교적 손쉽게 병렬 프로그래밍을 구현할 수 있으며 스레드의 라이프 사이클을 관리할 수 있다.
어노테이션
어노테이션을 이용하면 간단한 선언만으로도 메서드나 변수의 행동을 정의할 수 있다. 특히 많이 사용되고 있는 스프링 프레임워크는 어노테이션을 이용한 대표적인 예이다. 이외에도 다양한 개발 프레임워크와 테스트 도구 등에서 어노테이션을 이용해서 개발을 지원하고 있다.
Enum
자바 개발자들은 데이터구조를 좀 더 손쉽게 정의하고 사용할 수 있는 열거형(Enum) 기능을 원했고 자바 5에서 추가되었다. 이를 이용해 클래스, 인터페이스, 열거형으로 소스코드를 작성할 수 있게 되었다.
vararg
메서드의 입력 파라미터를 유연하게 가져갈 수 있도록 기능이 추가되었다. 이전까지는 원하는 파라미터 개수만큼 메서드에 모두 기술해야 했지만 vararg 기능이 추가된 이후 데이터 타입만 선언하면 복수의 파라미터를 전달할 수 있게 되었다.
오토 박싱/언박싱
자바는 객체 지향언어를 지향하고 있어서 모든 데이트를 객체화하지만, 예외적으로 기본형인 int, long, float, double 등을 제공하고 있다. 하지만 기본형 타입을 컬렉션에서 활용하거나 제네릭으로 선언해서 사용하기 위해서는 이와 연관된 래퍼 클래스인 Integer, Double 등을 별도로 선언해서 만들어야 했다. 자바 5에서는 오토 박싱/언박싱 기능을 통해 개발자가 기본형 데이터를 래퍼 클래스로 직접 변화하지 않아도 언어 차원에서 자동 변환이 가능하도록 보강되었다. 단 오토 박싱/언박싱은 성능상 비용이 들어가는 작업이므로 사용 시 주의해야 한다.
자바 6 - 자바 5의 안정화 버전
항목
내용
G1가비지 콜렉션
가상 머신의 성능에 가장 크게 영향을 주는 것 중 하나가 가비지 컬렉션이다. G1 가비지 컬렉터는 정확히는 버전 6의 중간 버전부터 추가된 기능으로 기존에는 힙 메모리 영역을 영과 올드 영역으로 분활해서 괸리 했지만 버전 6부터는 해당 영역 구분을 없애고 IMB 크기의 영역 (‘리전(rigion)’ 이라고 부른다)으로 구분해서 메모리를 관리한다. Full GC 발생을 최소화하기 위함이다. 자바 7부터는 기본 가비지 컬렉터로 사용한다.
데스크톱 API
데스크톱 API는 자바를 이용해서 UI를 개발할 때 운영체제의 기본 설정값을 기반으로 애플리케이션을 실행하고 출력 등을 편리하게 개발할 수 있도록 해준다. 이 기능을 이용해서 HTML 파일을 열면 OS에 기본으로 설정한 브라우져가 실행된다. 예를 들어 리눅스에서는 파이어폭스, 윈도우에서는 엣지가 실행된다.
자바 컴파일 API
자바 코드에서 직접 자바 컴파일러를 호출할 수 있는 API를 제공한다. 이를 통해 자바 어플리케이션에서 자바 소스 코드를 컴파일하고 실행할 수 있다.
자바 7 - 자바 6 이후 5년 만에 발표
항목
내용
파일 NIO 2.0
자바 7에서 가장 관심 있게 살펴볼 만한 기능으로, 파일 처리를 위한 새로운 기능을 제공한다. 기존에는 다양한 운영체제에서 파일을 처리할 때 예상치 못한 에러가 발생하거나 기능이 부족한 점 등이 문제로 거론되었다. File NIO는 기능이 풍부하고 처리 속도도 개선되었다. 다만 기존에 사용하던 java.io.File 클래스와 개념이 완전히 달라서 새로 공부해야 하는 부담감이 있다.
포크/조인 프레임워크
자바 5에서 처음 등장한 컨커런트API에 포크/조인 기능이 추가되었다. 이 기능을 이용하면 기존 멀티 스레드를 생성하는 것에 더해서 라이프 사이클을 관리하고 모니터링할 수 있다.
다이아몬드 연산자
제네릭의 선언 방법이 개선되었다. 변수 선언 시 제네릭의 타입을 이미 선언하였다면 객체 생성 시에는 제네릭 타입을 다시 기입할 필요 없이 다이아몬드 연산자 만 기술하면 된다.
try-with-resource
자바로 개발한 애플리케이션에서 메모리 누수가 발생하는 중요한 원인 중 하나가 자원을 사용한 이후 종료시키지 않는 것이다. 이런한 작업은 굉장히 단순하고 반복적으로 이루어지지만 세심하게 작업하지 않으면 치명적인 오류가 생길 수 있다. 자바 7에서는 자원의 종료를 언어 차원에서 보장하고 있으며, 이 기능을 이용할 경우 안정적인 자원 관리뿐만 아니라 소스 코드 작성량도 현저히 줄어든다.
예외 처리
예외 처리를 위해 try catch 문장을 작성할 때 경우에 따라서 많은 catch 문장을 작성해야 한다. 심지어 catch 절 안에 처리하는 로직이 같더라도 반복적인 작업이 발생한다. 자바 7에서는 하나의 catch를 걸어 여러 개의 Exception을 처리할 수 있도록 개선했다.
자바 8
변화의 수준이 파격적인 버전
람다와 함수형 프로그래밍을 이용하다가 이전 소스대로 되돌리는 일이 발생하기도 하면서, 자바 8 이상의 가상머신을 사용하면서 이전 버전의 자바로 개발하는 경우가 많음.
항목
내용
람다 표현식
자바 언어 역사상 가장 큰 변화가 자바 8의 람다 채용이다. 별도의 익명 클래스를 만들어서 선언하던 방식을 람다를 통해 대폭 간소화할 수 있으며, 함수형 프로그래밍, 스트림 API 그리고 컬렉션 프레임워크의 개선 등에 영향을 주었다. 영향이 큰 만큼 개발자들의 저항이 가장 심한 신기술이기도 하다.
함수형 인터페이스
람다와 더불어 자바 8의 큰 변화 중 하나이다. 함수형 인터페이스는 람다 표현식을 사용할 때 만들어야 하는 하나의 메서드를 가진 인터페이스 생성을 줄여준다. 또한 람다 표현식을 위한 인터페이스 사용 시 표준 가이드 및 의사소통 용어로도 사용한다.
메서드 참조
기존에는 값과 객체 참조 만을 메서드의 인수로 전달할 수 있었지만 자바 8부터는 특정 메서드를 메서드 인수로 전달할 수 있게 되었다. 궁극적으로는 복잡한 람다 표현식을 메서드 참조로 간략하게 만들 수 있고 재사용성도 높일 수 있으며 람다에 익숙하지 않은 개발자도 소스코드를 쉽게 해석할 수 있다
스트림 API
람다 표현식, 함수형 인터페이스 그리고 메서드 참조를 이용한 최종 산출물이 바로 스트림 API이다. 앞서 설명한 3가지 기술이 스트림 API를 위해 만들어진 것이라는 얘기가 있을 정도로 스트림 API는 혁신적인 기능을 제공한다. 스트림 API를 이용하면 기존 컬렉션 프레임워크를 이용할 때 보다 간결하게 코드를 작성할 수 있으며 병렬처리, 스트림 파이프라인 등을 통해 하나의 문장으로 다양한 데이터 처리 기능을 구현할 수 있다.
날짜와 시간 API
자바 8에서 새롭게 선보이는 날짜와 시간 API는 기존 Date와 Calendar 클래스의 기능 부족과 비표준적인 명명 규칙, 그리고 일관되지 못한 속성값 등의 문제를 해결하기 위해 새롭게 추가되었다. 명명 규칙을 새로 정의하고 각 클래스 간의 역할을 분명히 분배하여 개발자들의 혼란을 최소화하였으며 멀티 스레드 환경에서의 안정성을 보장하고 있다.
인터페이스 개선
자바 8 이전의 인터페이스에는 구현 내용이 없는 public 메서드 명세서만 작성이 가능하고 인터페이스를 구현한 클래스에서 상세 내용을 정의해야 했다. 때문에 인터페이스에 메서드를 추가하면 이를 구현한 모든 클래스에 컴파일 에러가 발생했다. 특히 컬렉션 프레임워크와 같이 인터페이스를 기반으로 동작하는 프레임워크는 기능 추가나 개선을 어렵게 하는 가장 대표적인 요인이었다. 자바 8에서는 default 키워드를 이용해서 인터페이스에 메서드를 추가하고 직접 내용을 정의할 수 있어서 인터페이스의 메서드 추가로 인한 문제점을 해소할 수 있다.
Optional
자바를 개발하면서 null 값 때문에 고민해 보지 않은 개발자가 없을 정도로 null 값은 굉장히 중요한 부분이다. 자바 8에서는 null 값을 확인하고 관리할 수 있는 새로운 기능을 제공한다.
Completable Future 기능
자바 8에서 멀티 스레드 프로그래밍 시에 중요한 기능 중 하나가 Completable Future이다. Completable Future는 기존 Future 인터페이스에서 제공하는 기능을 개선하였다.
자바 9 - 자바 8 이후 3년 만에 발표
항목
내용
자바 모듈화
자바 9에서 가장 핵심이 되는 내용이다. 자바 모듈화(혹은 자바 모듈 시스템)는 실행, 컴파일, 빌드 시점에 결합할 수 있도록 JDK를 모듈로 분할할 수 있게 해주는 기능이다. 모듈화를 통해 자바 SE뿐만 아니라 자바 EE 기반으로 대규모 소프트웨어를 개발할 때 더욱 용이하게 라이브러리를 관리할 수 있다.
REPL 기능 JShell
REPL(Read-Eval-Print-Loop)은 자바 진영의 오랜 숙원 프로젝트 중 하나이다. 프로젝트 쿨라(Project Kulla) 7에서 개발되었고 자바 9에 포함되어 배포되었다. REPL인 JShell을 이용하면 별도의 컴파일이나 클래스의 선언 없이도 코드를 작성하고 테스트할 수 있다. 간단한 코드 검증이나 교육 등에 유용하게 사용할 수 있다.
통합 JVM 로깅
자바 9에서는 통합된 JVM의 로깅 기능을 제공한다, 자바를 실행할 때 -Xlog 파라미터 옵션을 적용하면 통합 JVM 로깅 기능이 동작하여 ERROR, WARNING, INFO , DEBUG와 ERROR 레벨에 따라 로그를 STDOUT, STDERR 그리고 파일에 남길 수 있다.
HTML5 자바 DOC
자바 8 까지는 javadoc 명령어를 이용해서 API 문서를 생성하면 HTML4.0기반으로 파일이 생성되었으나 자바 9부터는 javadoc 명령어에 -html5 파라미터 옵션을 적용하면 HTML5로 결과물이 생성된다. HTML5로 출력된 자바 DOC의 가장 큰 차별점은 별도의 서버 도움 없이 검색 기능을 사용할 수 있다는 점이다.
tyr-with-resource 구문 개선
자바 7에서 처음 선보인 try-with-resource가 개선되었다. 자바 7에서는 관리하고자 하는 자원 객체를 반드시 try 구문에서 선언해야 했는데 자바 9에서는 try 구문 외부에서도 선언이 가능해졌다.
인터페이스 메서드 형식 추가
자바 8에서 인터페이스 default 메서드와 static 메서드를 정의하는 기능을 제공하였으며 자바 9에서는 private 메서드도 인터페이스 내에 추가할 수 있게 되었다, 과거 자가 8에서는 public 메서드에 한해 default 메서드를 생성할 수 있었기 때문에 public 접근자를 남용하게 되고 private로 빼거나 공통화 시킬 수 있는 것도 기능적인 하계로 사용할 수 없었다. 하지만 자바 9부터는 private 메서드를 이용해서 이러한 한계를 극복할 수 있게 되었다.
다이아몬드 연산자 개선
자바 7에서 새롭게 선보인 다이아몬드 연산자는 코드의 가독성을 높이는데 큰 역할을 하였지만 익명 클래스에는 사용할 수없는 제약이 있었다. 자바 9에서는 익명 클래스에서도 다이아몬드 연산자를 사용할 수 있게 되었다.
프로세스 API
프로세스 정보에 접근할 수 있는 새로운 API이다. 모든 프로세스, 현재 프로세스, 자식 프로세스 그리고 종료 프로세스 등의 정보를 조회하고 관리할 수 있는 기능을 제공한다.
Completable Future 개선
자바 8에서 처음 소개된 Completable Future의 기능이 개선되었다. 기존에는 코드를 실행하는 데 초점을 맞췄다면 자바 9에서는 타임아웃 기능과 지연 기능이 추가되었다.
반응형(Reactive) 스트림 API
자바 5에 추가된 컨커런트 API는 자바 버전이 업그레이드될 때마다 지속적으로 기능이 추가되었다. 자바 9에서는 반응형 프로그래밍을 위한 FLOW 기능이 추가되었다. 이 기능은 발행자(Publisher) 와 구독자 (Subscriber)를 지정하고 상호 연계할 수 있는 프레임워크를 제공한다.
자바 10
2017년도 자바 컨퍼런스에서 자바의 새 버전을 6개월마다 발표하겠다 공표
항목
내용
로컬 변수 형식 추론
로컬 변수 선언을 할 때 특정한 데이터 타입을 지정하지 않아도 된다. 자바스크립트와 마찬가지로 var 키워드를 이용해서 변수를 선언을 하고 뒤에 할당한 데이터의 값에 따라 자바 컴파일러가 형식을 추론해서 적용한다 단, var를 이용할 경우 반드시 해당 문장에서 객체 생성까지 해야한다 예들 들면 다음과 같다 var myList : new ArrayList();
G1 GC 개선
자바 10은 외부적인 기능보다는 내부적인 변화에 중점을 두었다. 대표적인 것이 자바 9의 안정화와 G1가비지 컬렉터의 성능 향상이다.
자바 11
버전 및 라이선스 정책이 변경되 이후 처음 나온 장기 지원 버전(Long Term Support, LTS) 지속적인 업그레이드와 패치 작업 및 기술 지원을 제공
자바 9에 인큐베이팅 형태로 넣었던 HTTP API를 정식으로 포함했다. 이 API는 기존에 제공되는 URLConnection 기반의 HTTP 개발보다 개선된 기능과 명명 규칙을 제공한다
컬렉션 객체를 배열로 변경하는 기능
컬렉션 인터페이스에 toArray 메서드가 추가되었다. 이 메서드를 통해서 컬렉션 객체를 배열로 변환하면 별도의 반복문을 작성하지 않고 메서드 호출만으로 처리할 수 있다.
var 키워드 지원 확대
자바 10에서 var 키워드로 변수를 선언하면 타입 추론으로 객체를 생성할 수 있는 기능이 추가되었다. 자바 11에서는 여기에 더해 람다 표현식에서도 var를 사용해서 변수를 선언할 수 있게 했다 기존에 (String x) -> System.out.println(x)로 하던 것을 (var x) -> System.out.println(x)처럼 사용할 수 있다.
String 클래스 지원 확대
문자열을 표현하는 String 클래스에 편리하게 사용할 수 있는 메서드를 추가했다. 블랭크를 판단하는 isBlank, 여러 줄로 되어 있는 문자열을 스트림 API 객체로 생성할 수 있는 lines, 공배을 지우기 위한 strip, stripLeading, stripTrailing등을 추가했다.
자바 12
항목
내용
스위치 문장 개선(초안 1)
스위치 문장이 개선되었다. 조건 문장(case)에 패턴 형태로 정의할 수 있는 문법이 추가되었고 기준과 다르게 break 문을 사용하지 않아도 자동 종료된다. 특히 조건 문장을 람다 표현식 형태로 작성할 수 있게 되었다. break 키워드에는 문장을 종료하는 것 외에 특정한 문자열을 리턴하는 기능을 추가했다. 그동안 선택 사항이던 default 문장이 새로운 스위치 문장에서는 반드시 추가해야 하는 필수 사항이 되었고 생략할 경우 컴파일 에러가 발생한다.
파일 비교
파일 NIO의 Files에 두 개의 파일의 일치 여부를 확인하는 메서드가 추가되었다.
자바 13 - 2020년 9월 발표
항목
내용
스위치 문장 개선 (초안 2)
자바 12에 소개된 새로운 스위치 문자에 기능을 추가했다, break 대신 yield 키워드를 사용하도록 변경했고 하나의 조건(case)에 여러 개의 문장을 작성할 수 있게 되었다.
텍스트 블록(초안)
여러 줄에 걸쳐서 문자열을 작성하기 위해서는 StringBuiler를 이용하거나 + 기호로 문자열을 연결하는 작업을 해야 하지만 텍스트 블록을 이용하면 그러한 수고 없이 코딩이 가능하다. 원하는 블록을 “"”으로 감싸면 문자열 사이에 캐리지 리턴 값이 있더라도 하나의 문장으로 작성할 수 있다. 이것을 처리하기 위해 String 클래스도 변경했다.
자바 14
항목
내용
스위치 문장 개선(정식)
자바 12와 13에 걸쳐 초안 형태로 새롭게 소개된 스위치 문장의 개선된 내용이 자바 14에서 정식으로 추가되었다. 정식 버전으로 추가되었든 것을 제외하면 자바 13의 기능과 차이는 없다.
instanceof 개선(초안)
객체의 유형을 확인하기 위한 instanceof 문법에 패턴으로 판단할 수 있는 기능이 추가되었다.
record 키워드 추가(초안)
데이터를 저장하고 표현하기 위해 getter와 setter 메서드를 생성하고 equals와 hashCode 등의 메서드를 구현하였지만 record 키워드를 이용해서 데이터를 저장하면 컴파일러가 자동으로 해당 기능들을 추가해 준다. 이 기능을 이용하면 VO(Value Object)와 같은 데이터 정의 목적의 클래스 선언이 쉽고 빨라진다