Java 공식문서 파헤치기

Java

목록 보기
19/19

https://www.java.com/ko/

현재는 Oracle 사에서 Java를 인수하고 관리하고 있다.


자바의 버전 역사를 알아보자.

https://www.java.com/releases/

릴리즈 타입 (Release Types)

버전마다 타입이 다르다. 현재 사용 중인 타입들:

타입설명
Feature ReleaseJava SE 플랫폼 스펙이 바뀔 수 있는 버전. API 추가/deprecated/제거 가능. 6개월마다 나옴
Patch Release치명적인 버그(보안 아님) 생겼을 때 비정기적으로 나오는 긴급 패치
Security Alert (SA)보안 취약점 발견됐을 때 비정기적으로 나오는 긴급 보안 패치
CPU Release모든 지원 버전에 동시에 보안 취약점 수정 + LTS 버전은 일반 유지보수도 포함

그리고 더 이상 안 쓰는 옛날 타입들:

타입설명
Major ReleaseJDK 9 이전에 쓰던 방식. 기능이 준비될 때까지 날짜를 미뤘음. JDK 10부터 날짜 기반으로 바뀌면서 Feature Release로 이름 변경
Minor Release수정사항이 많거나 새 기능, 포트, OS 업그레이드 있을 때
PSU ReleasePatch Set Update. CPU랑 같은 날 나오는데 보안 수정 + 추가 기능 수정 포함
Update Release버그 수정, 플랫폼/서드파티 업데이트 위주
Security Release2008년 이전에 보안 취약점을 각 버전별로 따로 고치던 방식
Emergency Release (ER)보안이든 아니든 비정기 긴급 릴리즈
Performance Release성능 개선 집중 버전. 주로 HotSpot 업데이트 포함

릴리즈 날짜 규칙

2013년부터 Oracle CPU 스케줄에 맞춰서 릴리즈 날짜가 고정됐다.

  • CPU 릴리즈 → 1월, 4월, 7월, 10월 셋째 주 화요일
    • 2022년 4월 이전에는 "17일에 가장 가까운 화요일" 이었음
  • Feature 릴리즈 → 3월 중순, 9월 중순

즉 자바는 1년에 2번 새 버전이 나오는 구조이다.


LTS vs 일반 버전

문서에 나온 지원 기간 표를 보면:

LTS 버전들 (장기 지원)

버전출시일지원 종료
Java 82014.032030.12
Java 112018.092032.01
Java 172021.092029.09
Java 212023.092031.09
Java 252025.092033.09

일반 버전들 (단기 지원)

Java 22 → 2024.03 출시, 2024.09 지원 종료 (6개월)
Java 23 → 2024.09 출시, 2025.03 지원 종료 (6개월)
Java 24 → 2025.03 출시, 2025.09 지원 종료 (6개월)

일반 버전은 딱 6개월만 지원하고 끝난다. 그래서 실무에서는 LTS만 쓴다.

현재 계획된 미래 버전

Java 26 → 2026.03.17 출시 (이미 나옴)
Java 27 → 2026.09 예정
Java 28 → 2027.03 예정
Java 29 LTS → 2027.09 예정

LTS는 3버전마다 나오는 패턴 (17 → 21 → 25 → 29)


버전 별 변경사항

https://docs.oracle.com/en/java/javase/26/language/java-language-changes-release.html#GUID-6459681C-6881-45D8-B0DB-395D1BD6DB9B

Java 9 변경사항

  1. 모듈 시스템 (Project Jigsaw)
    자바 9 최대 변화다. 모듈이라는 새로운 개념이 생겼다.
// module-info.java
module com.myapp {
    requires java.sql;      // 이 모듈 필요
    exports com.myapp.api;  // 이 패키지만 외부 공개
}

쉽게 말하면 패키지보다 더 큰 단위로 코드를 캡슐화하는 것. 내가 공개하고 싶은 패키지만 exports로 열어주고 나머지는 외부에서 접근 못 하게 막을 수 있음

  1. try-with-resources 개선
// Java 8 이전 - 새 변수 선언해야 했음
Resource resource1 = new Resource("r1");
try (Resource r1 = resource1) { ... }

// Java 9 - 이미 있는 변수 그냥 쓰면 됨
Resource resource1 = new Resource("r1");
try (resource1) { ... }
  1. private 인터페이스 메서드 지원
interface MyInterface {
    default void publicMethod() {
        sharedLogic(); // private 메서드 공유 가능
    }
    
    private void sharedLogic() { // Java 9부터 가능
        System.out.println("공통 로직");
    }
}
  1. underscore 식별자 사용 금지
int _ = 10; // Java 9부터 컴파일 에러

Java 10 변경사항

var (지역변수 타입 추론)

// 이전
HashMap<String, List<Integer>> map = new HashMap<>();

// Java 10부터
var map = new HashMap<String, List<Integer>>();
var list = new ArrayList<String>();
var number = 10;

타입을 컴파일러가 알아서 추론해준다. 지역변수에만 사용 가능


Java 11 변경사항

var를 람다 파라미터에도 사용 가능

// Java 11부터
var list = List.of(1, 2, 3);
list.forEach((var x) -> System.out.println(x));

// 이게 왜 유용하냐면 어노테이션 붙일 때
list.forEach((@NotNull var x) -> System.out.println(x));

Java 12 변경사항

Switch Expression (preview)

// 기존 switch - 이렇게 길었음
String result;
switch (day) {
    case MONDAY:
        result = "월요일";
        break;
    case TUESDAY:
        result = "화요일";
        break;
    default:
        result = "기타";
}

// Java 12 preview - 화살표 문법
String result = switch (day) {
    case MONDAY -> "월요일";
    case TUESDAY -> "화요일";
    default -> "기타";
};

훨씬 짧아졌고 값을 바로 반환할 수 있게 됨


Java 13 변경사항

  1. Switch Expression (2차 preview)
    12에서 break로 값 반환하던 걸 yield 키워드로 바꿈
String result = switch (day) {
    case MONDAY -> "월요일";
    default -> {
        String s = day.toString();
        yield s.toLowerCase(); // yield로 값 반환
    }
};
  1. Text Blocks (preview)
// 이전 - 지저분함
String json = "{\n" +
              "  \"name\": \"홍길동\",\n" +
              "  \"age\": 30\n" +
              "}";

// Java 13 preview - 깔끔함
String json = """
              {
                "name": "홍길동",
                "age": 30
              }
              """;

여러 줄 문자열을 이스케이프 없이 그냥 쓸 수 있게 됨


Java 14 변경사항

  1. Switch Expression 정식 출시
    12, 13에서 preview였던 것이 정식 기능이 됨

  2. instanceof Pattern Matching (preview)

// 이전 - 형변환을 두 번 해야 했음
if (obj instanceof String) {
    String s = (String) obj; // 형변환 따로
    System.out.println(s.length());
}

// Java 14 preview - 한 번에 처리
if (obj instanceof String s) {
    System.out.println(s.length()); // s 바로 사용
}
  1. Record (preview)
// 이전 - DTO 클래스
public class Point {
    private final int x;
    private final int y;
    public Point(int x, int y) { this.x = x; this.y = y; }
    public int x() { return x; }
    public int y() { return y; }
    // equals, hashCode, toString 다 구현해야 함
}

// Java 14 preview - 한 줄로 끝
public record Point(int x, int y) {}

불변 데이터 객체를 간결하게 선언 가능하다. getter, equals, hashCode, toString 자동 생성


Java 15 변경사항

  1. Text Blocks 정식 출시
    13, 14에서 preview였던 것이 정식 기능이 됨

  2. Sealed Classes (preview)

// 이 클래스를 상속할 수 있는 클래스를 딱 지정
public sealed class Shape
    permits Circle, Rectangle, Triangle { }

public final class Circle extends Shape { }
public final class Rectangle extends Shape { }
// Triangle 외에 다른 클래스가 Shape 상속하면 컴파일 에러

상속 가능한 클래스를 제한할 수 있게 됨. 보안/설계 측면에서 유용

  1. Record, instanceof Pattern Matching 2차 preview
    계속 다듬는 중

Java 16 변경사항

  1. Record 정식 출시
    14, 15에서 preview였던 것이 정식 기능이 됨
public record Point(int x, int y) {} // 이제 그냥 씀
  1. instanceof Pattern Matching 정식 출시
if (obj instanceof String s) {
    System.out.println(s.length()); // 정식 기능
}

Java 17 변경사항

  1. Sealed Classes 정식 출시
public sealed class Shape permits Circle, Rectangle { }
// 정식 기능으로 확정
  1. Pattern Matching for switch (preview)
// instanceof + switch 합친 것
String result = switch (obj) {
    case Integer i -> "정수: " + i;
    case String s -> "문자열: " + s;
    case null -> "null";
    default -> "기타";
};

타입 체크 + 형변환 + switch를 한 번에 처리


Java 18 (2022.03) - 일반 버전

  1. Pattern Matching for switch 2차 preview
    switch 레이블 지배성 검사가 추가됨. 상수 레이블이 guarded 패턴 레이블보다 앞에 와야 하고, guarded 패턴 레이블이 non-guarded 타입 패턴 레이블보다 앞에 와야 함. 또한 제네릭 sealed 클래스를 고려한 완전성 검사가 확장됨.

언어 변경사항은 이게 전부. 나머지는 JVM, API 레벨 변경


Java 19 (2022.09) - 일반 버전

  1. Pattern Matching for switch 3차 preview
    guarded 패턴 레이블의 문법이 when 절을 사용하는 방식으로 바뀜. switch 블록에 null 케이스 레이블이 없는데 null이 들어오면 NullPointerException 발생. 컴파일 타임엔 exhaustive하지만 런타임엔 아닌 경우 MatchException 발생.
// when 절 추가된 모습
switch (obj) {
    case Integer i when i > 0 -> "양수";
    case Integer i            -> "음수 또는 0";
}
  1. Record Patterns preview 시작
    Record 패턴은 타입, 레코드 컴포넌트 패턴 리스트, 선택적 식별자로 구성됨. 중첩 Record 패턴과 타입 패턴을 함께 써서 강력하고 선언적인 데이터 탐색 및 처리 가능.
record Point(int x, int y) {}

if (obj instanceof Point(int x, int y)) {
    // x, y 바로 꺼내서 사용
}

Java 20 (2023.03) - 일반 버전

  1. Pattern Matching for switch 4차 preview
    exhaustive switch에서 런타임에 일치하는 switch 레이블이 없으면 IncompatibleClassChangeError 대신 MatchException 발생하도록 변경. switch 레이블 문법도 단순화됨. 제네릭 Record 패턴의 타입 인자를 컴파일러가 추론 가능해짐.

  2. Record Patterns 2차 preview
    제네릭 Record 패턴의 타입 인자 추론 가능. Record 패턴을 enhanced for 문에서도 쓸 수 있게 됨. 명명된 Record 패턴은 제거됨.

// enhanced for에서 record 패턴 사용
for (Point(int x, int y) : points) {
    System.out.println(x + ", " + y);
}

사실상 Java 21 LTS 준비 단계


Java 21 (2023.09) - LTS

  1. Record Patterns 정식 출시
    Java SE 19에서 preview 시작, 이번에 정식 기능이 됨. 단, enhanced for 문 헤더에서의 Record 패턴 지원은 제거됨.

  2. Pattern Matching for switch 정식 출시
    Java SE 17에서 preview 시작, 이번에 정식 기능이 됨. 괄호 패턴은 제거됨. switch 표현식과 문에서 한정된 enum 상수를 case 상수로 쓸 수 있게 됨.

// 완성된 모습
String result = switch (obj) {
    case Integer i when i > 10 -> "큰 정수";
    case Integer i             -> "작은 정수";
    case String s              -> "문자열: " + s;
    case null                  -> "null";
    default                    -> "기타";
};
  1. String Templates preview 시작
    문자열 리터럴과 텍스트 블록에 임베디드 표현식과 템플릿 프로세서를 결합해서 특수한 결과를 생성하는 기능.
String name = "홍길동";
String msg = "안녕하세요, \{name}님";
  1. Unnamed Patterns and Variables preview 시작
    이름 없는 패턴은 컴포넌트의 이름이나 타입 없이 Record 컴포넌트를 매칭함. 이름 없는 변수는 초기화는 되지만 사용하지 않는 변수. 둘 다 밑줄(_)로 표기.
// 안 쓰는 변수 _ 로 표시
if (obj instanceof Point(int x, _)) {
    // y는 필요없을 때
}
  1. Unnamed Classes and Instance Main Methods preview 시작
    클래스 선언 없이 단일 클래스 프로그램을 간결하게 작성할 수 있게 해줌. 나중에 더 고급 기능을 쓸 때 자연스럽게 확장 가능하도록 설계됨.
// 클래스 선언 없이 main 바로 작성 (초보자 친화적)
void main() {
    System.out.println("Hello World");
}

Java 22 (2024.03) - 일반 버전

  1. Unnamed Variables & Patterns 정식 출시
    Java SE 21에서 preview, 이번에 정식 기능. Java SE 21과 내용 동일.

  2. Statements Before super(...) preview 시작
    생성자에서 명시적 생성자 호출 전에 인스턴스를 참조하지 않는 문장들을 추가할 수 있게 됨.

class Child extends Parent {
    Child(int value) {
        // Java 22 이전엔 여기에 아무것도 못 씀
        int adjusted = Math.abs(value); // 이제 가능
        super(adjusted);
    }
}
  1. String Templates 2차 preview
    21에서 preview였던 것 계속 다듬는 중

  2. Implicitly Declared Classes and Instance Main Methods 2차 preview
    명시적 클래스 선언 없이 선언된 클래스를 "암묵적으로 선언된 클래스"라고 부르게 됨. main 메서드 선택 절차도 단순화됨.


Java 23 (2024.09) - 일반 버전

  1. Primitive Types in Patterns, instanceof, switch preview 시작
    이번 버전의 핵심 기능. 모든 패턴 컨텍스트에서 기본형 타입 패턴 사용 가능. instanceof 연산자와 switch 표현식/문이 모든 기본형 타입과 동작하게 됨.
// 기존엔 int같은 기본형을 패턴에 못 씀
// Java 23부터 가능
switch (value) {
    case int i when i > 0  -> "양수";
    case int i             -> "음수";
    case double d          -> "실수";
}
  1. Module Import Declarations preview 시작
    모듈이 export하는 모든 패키지를 한 번에 import할 수 있게 됨.
// 이전 - 하나하나 import
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

// Java 23 - 모듈 통째로 import
import module java.base;
  1. String Templates 결국 폐기
    JDK 21에서 preview, JDK 22에서 재preview됐지만 현재 형태로는 적합하지 않다는 결론. 더 나은 설계에 대한 합의가 없어서 기능 자체를 철회. JDK 23에 포함되지 않음.

  2. Flexible Constructor Bodies 2차 preview
    생성자 유연성 계속 다듬는 중


Java 24 (2025.03) - 일반 버전

  1. Primitive Types in Patterns 2차 preview
    Java SE 23과 동일하게 유지, 변경 없음.

  2. Module Import Declarations 2차 preview
    타입 import-on-demand 선언이 모듈 import 선언보다 우선순위가 높아짐. java.se 모듈이 java.base를 transitively require하게 돼서 java.se 모듈 import 시 Java SE API 전체를 import하게 됨.

  3. Flexible Constructor Bodies 3차 preview
    계속 다듬는 중


Java 25 (2025.09) - LTS

  1. Module Import Declarations 정식 출시
    Java SE 23에서 preview 시작, 이번에 변경 없이 정식 기능이 됨.

  2. Compact Source Files and Instance Main Methods 정식 출시
    Java SE 21에서 preview 시작, 이번에 정식 기능이 됨. IO 클래스가 java.io 패키지 대신 java.lang 패키지로 이동해서 모든 소스 파일에서 암묵적으로 import됨. IO 클래스의 static 메서드는 더 이상 compact 소스 파일에 암묵적으로 import되지 않아서 IO.println("Hello") 처럼 명시적으로 호출해야 함.

  3. Flexible Constructor Bodies 정식 출시
    Java SE 22에서 preview 시작, 이번에 정식 기능이 됨. 변경 없음.

  4. Primitive Types in Patterns 3차 preview
    계속 다듬는 중


Java 26 (2026.03) - 일반 버전 (최신)

  1. Primitive Types in Patterns 4차 preview
    unconditional exactness 정의가 강화됨. switch 구문에서 더 엄격한 지배성 검사가 적용됨.

아직 다듬는 중


Java 8 변경사항

Java 8은 현대 자바의 시작점이라 불릴 만큼 변화가 컸다.

  1. Lambda (람다) ⭐ 최대 변화
// 이전
Runnable r = new Runnable() {
    @Override
    public void run() {
        System.out.println("실행");
    }
};

// Java 8
Runnable r = () -> System.out.println("실행");
  1. Stream API ⭐
// 이전
List<String> result = new ArrayList<>();
for (String s : list) {
    if (s.startsWith("A")) {
        result.add(s.toUpperCase());
    }
}

// Java 8
List<String> result = list.stream()
    .filter(s -> s.startsWith("A"))
    .map(String::toUpperCase)
    .collect(Collectors.toList());
  1. Optional
// null 처리를 명시적으로
Optional<String> name = Optional.ofNullable(getName());
name.ifPresent(n -> System.out.println(n));
String result = name.orElse("이름 없음");
  1. 새로운 날짜/시간 API
// 이전 Date, Calendar는 쓰기 불편하고 버그 많았음
// Java 8부터
LocalDate today = LocalDate.now();
LocalDateTime now = LocalDateTime.now();
Duration duration = Duration.between(start, end);
  1. 인터페이스 default 메서드
interface MyInterface {
    default void hello() {
        System.out.println("기본 구현");
    }
}
  1. 함수형 인터페이스
Function<String, Integer> len = s -> s.length();
Predicate<String> isEmpty = s -> s.isEmpty();
Consumer<String> print = s -> System.out.println(s);
Supplier<String> hello = () -> "Hello";

전체 요약

Java 8  (2014) LTS ⭐ → Lambda, Stream, Optional
                         현대 자바의 시작점

Java 9  (2017)      → 모듈 시스템 (대형 변화)
Java 10 (2018)      → var 추가
Java 11 (2018) LTS  → var 람다에도 적용
Java 12 (2019)      → switch 표현식 preview 시작
Java 13 (2019)      → Text Block preview 시작
Java 14 (2020)      → Record, instanceof 패턴매칭 preview 시작
Java 15 (2020)      → Sealed Class preview 시작
Java 16 (2021)      → Record, instanceof 패턴매칭 정식
Java 17 (2021) LTS ⭐→ Sealed Class 정식
                         switch 패턴매칭 preview 시작

Java 18 (2022)      → switch 패턴매칭 계속 다듬기
Java 19 (2022)      → Virtual Threads preview, Record Patterns preview
Java 20 (2023)      → 21 준비 단계
Java 21 (2023) LTS ⭐→ Virtual Threads, Record Patterns,
                         switch 패턴매칭 전부 정식

Java 22 (2024)      → super() 전 statements preview
Java 23 (2024)      → 기본형 패턴매칭 preview, String Templates 폐기
Java 24 (2025)      → 소소한 개선
Java 25 (2025) LTS ⭐→ 최신 LTS, 모듈 import 정식
Java 26 (2026)      → 현재 최신 버전 (일반)

자바 배우기

https://dev.java/learn/





profile
매일 1퍼센트씩 나아지기 ୧(﹒︠ ̫ ̫̊ ̫﹒︡)୨

0개의 댓글