[Java] Java 버전 별 특징
JDK 1.0
1996년 1월에 공개되었으며 발표 이전에 불린 이름은 Oak였다.
안정화 작업을 거친 1.0.2 버전에서 Java로 이름이 바뀌었다.
JDK 1.1
1997년 2월에 공개했으며 JDBC, Inner Class, Java Beans, RMI, Reflection, Unicode 지원, Internationalization 등이 추가되었다.
JavaBeans
JavaBeans는 자바로 작성된 소프트웨어 컴포넌트를 말한다.
뷰와 로직을 분리하여 일관된 방식으로 자바 클래스를 사용할 수 있도록 도와준다.
Beans 규약
- 기본 생성자가 반드시 존재해야 한다.
- 모든 속성은 비공개이다.
- 속성에 접근하고 꺼내올 수 있는 getter, setter 메서드를 구성한다.
- Serializable을 구현한다.
J2SE 1.2
1998년 12월에 공개했으며 Swing GUI, JIT, Collection Framework 등의 기능들이 추가되었다.
여기서 부터 약칭을 J2SE(Java 2 Standard Edition)으로 표기하기 시작했으며, 이 표기는 5까지 사용된다.
J2SE 1.3
2000년 3월에 공개했으며 HotSpot JVM, JNDI, JPDA, JavaSount 등이 추가되었다.
J2SE 1.4
2002년 2월에 공개했으며 assert, 정규표현식, IPv6, XML API, JCE, JSSE, Java Web Start 등이 추가되었다.
J2SE 5
2004년 9월에 공개했으며 Generics, Annotation, Concurrency API, Enumeration, Auto Boxing/Unboxing 등이 추가되었다.
이때부터 버전 표기에서 1을 빼기 시작했다.
Generics
기존 Collection Framework를 이용할 때 발생할 수 있는 ClassCastException을 컴파일 시간에 검증할 수 있다. 즉, 형변환 시 실수가 일어나는 것을 작성 중에 방지할 수 있는 것이다. 또 코드에 대한 데이터를 명확하게 하여 가독성을 높일 수 있다.
Concurrency API
이 API를 통해 병렬 프로그래밍, 멀티 스레드를 쉽게 구현할 수 있다.
Enumeration
데이터 구조를 더 쉽게 정의하고 사용할 수 있는 열거체로 다음과 같이 사용한다.
enum Color {
RED,
ORANGE,
BLUE
}
Java SE 6
2006년 12월에 공개했으며 Scripting Language Support, JDBC 4.0, Java Compiler API, Pluggable Annotation 등이 추가되었다.
또 가비지 컬렉터 G1 GC을 오직 테스트용으로만 사용하도록 추가했다.
이때부터 표기가 Java SE로 변경되었다.
Java SE 7 (LTS)
2011년 7월에 공개했으며 대표적인 변경사항은 다음과 같다.
Diamond Operator <>
General Class 초기화 시 Type Interface를 지원한다.
// Java SE 7 이전
List<Integer> list = new ArrayList<Integer>();
// Java SE 7 이후
List<Integer> list = new ArrayList<>();
Switch문에서 String 사용
switch(str) {
case "Spring":
System.out.println("봄");
break;
case "Summer":
System.out.println("여름");
break;
case "Fall":
System.out.println("가을");
break;
case "Winter":
System.out.println("겨울");
break;
default:
break;
}
try 문에서 자동 자원 관리 (Try-with-resources)
try() 내에 선언된 자원을 try가 종료될 때 자동으로 해제한다.
예를 들어, 다음과 같이 파일을 읽어들이는 코드를
BufferedInputStream bis = null;
try {
bis = new BufferedInputStream(new FileInputStream("file.txt"));
int data = -1;
while((data = bis.read()) != -1) {
System.out.print((char) data);
}
} finally {
if (bis != null) {
bis.close();
}
}
다음과 같이 쓸 수 있다. 이렇게 작성하면 try(...) 안에 선언된 객체의 close() 메서드들을 호출한다. 때문에 finally에서 close()를 명시적으로 호출해줄 필요가 없다.
단, AutoCloseable 인터페이스를 구현한 객체만 close()가 호출된다는 것을 조심하자. AutoCloseable도 Java 7부터 지원한다.
try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("file.txt"))) {
int data = -1;
while((data = bis.read()) != -1) {
System.out.print((char) data);
}
} catch (IOException e) {
e.printStackTrace();
}
그 외 변경사항은 다음과 같다.
- Dynamic Language 지원
- 이진수 리터럴, 숫자 리터럴에 _ 지원
- 새로운 Concurrency API 추가
- 새로운 File NIO 라이브러리 추가 등
Java SE 8 (LTS)
2014년 3월에 공개했으며 자세한 내용은 [Java 8 특징] 이 글을 참고하자.
Java SE 9
2017년 9월에 공개했으며 자세한 내용은 [Java 9 특징] 이 글을 참고하자.
Java SE 10
2018년 3월에 공개했으며 변경사항은 다음과 같다.
- var 키워드를 이용한 지역 변수 타입 추론
- 병렬 처리 가비지 컬렉션
- 개별 쓰레드로 분리된 Stop-The-World
- 루트 CA 목록
Java SE 10에서는 JDK의 레포지토리가 하나로 통합되었으며, JVM 힙 영역을 시스템 메모리가 아닌 다른 종류의 메모리에도 할당할 수 있게 되었다.
또 실험 기능으로 Java 기반의 JIT 컴파일러가 추가되었다.
Java SE 11 (LTS)
2018년 9월에 공개했으며 자세한 내용은 [Java 11 특징] 이 글을 참고하자.
Java SE 12
2019년 3월에 공개했으며 변경사항은 다음과 같다.
- 가비지 컬렉터 개선
- 마이크로 벤치마크 툴 추가
- 성능 개선
- 유니코드 11 지원
- Switch 표현 확장 (preview)
Java SE 13
2019년 9월에 공개했으며 변경사항은 다음과 같다.
Switch에서 yield 예약어 추가
var a = switch (day) {
case MONDAY, FRIDAY, SUNDAY:
yield 6;
case TUESDAY:
yield 7;
case THURSDAY, SATURDAY:
yield 8;
case WEDNESDAY:
yield 9;
};
그 외 변경사항은 다음과 같다.
- 다중 텍스트 블록(Multiline String) (Preview)
Java SE 14
2020년 3월에 공개했으며 대표적인 변경사항은 다음과 같다.
Switch 표현 확장
다음과 같이 작성하던 스위치 문을
switch(day) {
case MONDAY:
case FRIDAY:
case SUNDAY:
System.out.println(6);
break;
case TUESDAY:
System.out.println(7);
break;
case THURSDAY:
case SATURDAY:
System.out.println(8);
break;
case WEDNESDAY:
System.out.println(9);
break;
}
다음과 같은 형식으로도 쓸 수 있게 되었다.
switch (day) {
case MONDAY, FRIDAY, SUNDAY -> System.out.println(6);
case TUESDAY -> System.out.println(7);
case THURSDAY, SATURDAY -> System.out.println(8);
case WEDNESDAY -> System.out.println(9);
}
유용한 NullPointerExceptions
NullPointerExceptions 발생 시 어떤 변수가 null인지 설명한다.
author.age = 35;
---
Exception in thread *"main"* java.lang.NullPointerException:
Cannot assign field *"age"* because *"author"* is null
그 외 변경사항은 다음과 같다.
- instanceof 패턴 매칭 (preview)
- record (data object) 타입 지원 (preview)
Java SE 15
2020년 9월에 공개했으며 대표적인 변경사항은 다음과 같다.
다중 텍스트 블록(Multiline String)
여러 줄의 문자열을 쉽게 작성할 수 있다
String html = """
<html>
<body>
<p>Hello, world</p>
</body>
</html>
""";
그 외 변경사항은 다음과 같다.
- EdDSA 암호화 알고리즘 추가
- 봉인 클래스(Sealed Classes) (preview)
- 패턴 매칭 (2nd preview)
- 스케일링 가능한 낮은 지연의 가비지 컬렉터 추가(ZGC)
- 외부 메모리 접근 API (incubating)
- Solaris 및 SPARC 플랫폼 지원 제거
- Nashorn JavaScript Engine 제거
Java SE 16
2021년 3월에 공개했으며 대표적인 변경사항은 다음과 같다.
instanceof 패턴 매칭
instanceof 연산자 사용시 Object에서 component의 조건부 추출을 더 간결하고 안전하게 표현할 수 있다.
// java 16 이전
@Override
public boolean equals(Object obj) {
if (obj instanceof Student) {
Student student = (Student) obj;
if (this.studentNumber == student.studentNumber) {
return true;
} else {
return false;
}
}
return false;
}
// java 16 이후
@Override
public boolean equals(Object obj) {
if (obj instanceof Student student) {
if (this.studentNumber == student.studentNumber) {
return true;
} else {
return false;
}
}
return false;
}
Record
불변(immutable) 데이터 객체를 쉽게 생성할 수 있는 Record 라는 유형의 클래스가 추가되었다.
Record는 다음과 같은 특징을 가진다.
- final 클래스가 되어 abstract로 선언이 불가하며, 모든 클래스 멤버도 final이 된다.
- 자동으로 필드를 캡슐화 시킨다.
- 모든 클래스 멤버에 대한 생성자와 public을 갖는 getter, equals, hashCode, toString 메서드가 자동으로 생성된다.
이는 Kotlin의 Data class와 유사한 역할을 한다.
// 기존
public class User {
private final String nickname;
private final String phone;
public User(String nickname, String phone) {
this.nickname = nickname;
this.phone = phone;
}
public String getNickname() {
return this.nickname;
}
public String getPhone() {
return this.phone;
}
}
// java 16 이후
public record User(String nickname, String phone) {
}
그 외 변경사항은 다음과 같다.
- Vector API
- 자바 네이티브(JNI 등) 개발 시 C++14 규격 지원
- OpenJDK의 Version Controll을 Mercurial에서 Git으로 변경
- ZGC 기능 향상
- 유닉스 도메인 소켓 지원
- JNI를 대신할 외부 링크 방식의 인터페이스를 인큐베이팅을 통해 시작
- 값 유형의 클래스를 동기화에 사용 시의 경고 메시지가 개선됨
- jpackage 명령어를 통해 각 운영체제별 자바 프로그램을 설치 패키지(pkg, deb, msi 등)로 생성하는 기능이 정식으로 추가되어, 자바 프로그램을 손쉽게 배포하는 기능이 추가됨
- 자바 내부 API 접근에 대한 경고 무시기능이 강화되어 내부 API 접근 시도 시 기본적으로 오류와 함께 자바 프로그램이 종료될 수 있도록 강화
Java SE 17 (LTS)
2021년 9월에 공개했으며 변경사항은 다음과 같다.
봉인 클래스(Sealed Classes)
자바에서는 상속을 통해 코드를 재사용할 수 있지만 무분별한 상속은 오히려 설계와 가독성에 있어서 안좋은 영향을 끼친다. 때문에 Java 15에서 봉인 클래스가 Preview로 제안되었다.
봉인 클래스를 통해 허용되는 하위 유형을 정의하여 세분화된 상속 제어를 할 수 있다. 즉, 확장(extends)하거나 구현(implements)할 수 있는 클래스 또는 인터페이스를 지정하여 해당 허용된 것들만 상속/구현이 가능하도록 제한할 수 있다.
봉인 클래스는 다음과 같은 규칙이 있다.
- sealed 클래스와 permit된 서브 클래스는 동일한 모듈 또는 패키지에 속해야 한다.
- 모든 permit된 서브 클래스는 sealed 클래스를 확장(extends)해야 한다. -> 하지 않으면 컴파일 에러 발생
- 모든 permit된 서브 클래스는 수퍼 클래스에 의해 시작된 봉인을 이어갈지 선언해야한다.
- final: 더 이상 확장하지 않고 끝냄
- sealed: 자신도 봉인하여 자식 클래스를 가짐
- non-sealed: 봉인을 해제하여 다른 클래스가 확장할 수 있음
// 허용된(permits) 서브 클래스만 확장할 수 있도록 한다.
// permit된 서브 클래스는 다음 세 가지 상태를 가질 수 있다.
// final: 확장을 더 이상 못하게 한다.
// sealed: 자신도 자식을 가지고 봉인한다.
// non-sealed: 봉인을 해제한다.
sealed class Person permits Student, Professor {
}
// non-sealed를 선언하여 Professor 클래스의 봉인이 해제되었다.
non-sealed class Professor extends Person {
}
// sealed를 선언하여 봉인했다. 때문에 서브 클래스를 가져야 한다.
sealed class Student extends Person permits Freshman, Senior {
}
// final을 선언하여 더 이상 확장을 못하게 한다.
final class Freshman extends Student {
}
// 봉인을 해제했다.
non-sealed class Senior extends Student {
}
의사 난수 생성 API 확장
기본 legacy 랜덤(java.util.Random) 클래스를 확장, 리팩토링한 RandomGenerator 난수 생성 API가 추가되었다.
다음 코드를 통해 Java 17에서 사용 가능한 알고리즘을 확인할 수 있다.
RandomGeneratorFactory.all()
.map(factory -> String.format("%s: %s", factory.group(), factory.name()))
.sorted()
.forEach(System.out::println);
그 외 변경사항은 다음과 같다.
- 컨텍스트 기반의 역직렬화 필터링
- Foreign Function & Memory API (Incubator)
- 스위치 패턴 매칭 (Preview)
- AOT, JIT 컴파일러 제거
- Deprecate Security Manager
- Deprecate the Applet API for Removal
Java SE 18
2022년 3월에 공개했으며 변경 사항은 다음과 같다.
- Java API의 기본 Charset을 UTF-8로 지정
- 정적 파일을 서빙하는 기능만 있는 심플한 웹 서버 제공
- Java API Doc에 @snippet 태그 추가
- 리플렉션 기능 리팩터링 -> 메서드 핸들을 이용해 다시 구현
- Internet-Address Resolution SPI
- try 문 에서의 finally deprecate
- switch 문 패턴 매칭 (2nd preview)
- 외부 함수 및 메모리 API (2nd incubating)
- Vector API (3rd incubating)
Java SE 19
2022년 9월에 공개했으며 변경 사항은 다음과 같다.
- record 패턴 매칭 (preview)
- switch 문 패턴 매칭 (3rd preview)
- 가상 스레드 (preview)
- 외부 함수 및 메모리 API (preview)
- Vector API (4th incubating)
- 멀티스레드 프로그래밍을 단순화하는 Structured Concurrency API (incubating)
- Linux/RISC-V Port
Java SE 20
2023년 3월에 공개했으며 변경 사항은 다음과 같다.
- Scoped Values(범위가 지정된 값) (preview) -> 스레드 내부 및 스레드 간에 변경 불가능한 데이터를 공유할 수 있다
- record 패턴 매칭 (2nd preview)
- switch 문 패턴 매칭 (4th preview)
- 외부 함수 및 메모리 API (2nd preview)
- 가상 스레드 (2nd preview)
- Structured Concurrency API (2nd incubating)
'Language > Java' 카테고리의 다른 글
[Java] Mockito (0) | 2023.07.31 |
---|---|
[Java] hashCode() (1) | 2023.07.02 |
[Java] Java 11 특징 (0) | 2023.04.13 |
[Java] Java 9 특징 (0) | 2023.04.13 |
[Java] Java 8 특징 (0) | 2023.04.13 |
댓글
이 글 공유하기
다른 글
-
[Java] Mockito
[Java] Mockito
2023.07.31 -
[Java] hashCode()
[Java] hashCode()
2023.07.02 -
[Java] Java 11 특징
[Java] Java 11 특징
2023.04.13 -
[Java] Java 9 특징
[Java] Java 9 특징
2023.04.13