티스토리 뷰

Programming/BackEnd

[BE] Java 8에서 21로

오딩이 2026. 2. 9. 18:54

회사에서 올 해 프로젝트로 Java 8버전에서 21로 올리는 프로젝트가 뜬다고 한다

Java8을 아직도 쓰는것도 놀라운데 이 프로젝트에 참여할 수도 있다는게 놀라움

 

Java 8에서 21로 : 현대적 자바로의 대도약

1. Virtual Threads: 동시성 프로그래밍의 혁명 (Java 21)

가장 파급력이 큰 변화다. 기존 자바의 스레드(PlatformThread)는 OS 스레드와 1:1로 매핑되어 생성 비용이 비싸고 개수도 제한적이었다.

  • Java 8 : 요청 하나 당 스레드 하나를 할당하다보니, I/O 작업(DB 조회, API호출) 시 스레드가 차단되어 자원이 낭비되었음. 이를 해결하려면 복잡한 비동기 프로그래밍(WebFlux 등)이 강제되었다.
  • Java 21 : 수백만 개의 Virtual Thread를 생성할 수 있다. I/O 차단이 발생하면 JVM이 해당 가상 스레드를 대기 상태로 돌리고, 실제 OS 스레드에서는 다른 가상 스레드를 실행한다.

 

[코드 예시 : 가상 스레드 생성]

// 기존 방식 : 플랫폼 스레드 생성 (제한적)
Thread.ofPlatform().start(() -> System.out.println("Platform Thread"));

// Java 21 방식 : 가상 스레드 생성 (수백만 개 가능)
Thread.ofVirtual().start(() -> {
  System.out.println("Virtual Thread 시작");
});

// 스레드 풀 없이도 처리량이 폭발적으로 증가함
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
  IntStream.range(0, 10_000).forEach(i -> {
    executor.submit(() -> {
      Thread.sleep(Duration.ofSeconds(1));  // I/O 시뮬레이션
      return i;
    });
  });
}

 

2. Record & Pattern Matching : 간결하고 안전한 코드 (Java 14~21)

Java8에서는 데이터 객체(DTO)를 하나 만들려면 수십 줄의 Boilerplate 코드가 필요했다. 이제는 '언어 차원'에서 이를 해결한다.

  • Record: 불변 데이터를 저장하기 위한 특별한 클래스.
    필드, 생성자, getter, equals, hashCode, toString을 컴파일러가 자동으로 생성함.
  • Pattern Matching: instanceof로 타입을 확인한 뒤 강제 형변환(Casting)을 하던 번거로움이 사라짐

[코드 예시: Before vs After]

// Java 8 방식 (Lombok 의존 또는 수기작성)
public class User {
  private final String name;
  private final int age;
}

// Java 21 방식 (Record + Pattern Maching)
// 단 한 줄로 데이터 객체 정의
public record User(String name, int age) {}

public void process(Object obj) {
  // 1. Pattern Matching for instanceof: 타입 체크와 변수 선언을 동시에
  if (obj instanceof User user) {
    System.out.println("이름: "+user.name());  //user로 바로 접근
  }
  
  // 2. Switch Pattern Matching: switch문에서 복잡한 조건 처리
  String result = switch (obj) {
    case User u && u.age() > 18 -> "성인 유저: "+u.name();
    case User u -> "미성년 유저";
    case String s -> "문자열 데이터: "+s;
    default -> "알 수 없는 타입";
  };
}

 

3. Text Blocks: 가독성의 비약적 향상 (Java 15)

JSON이나 SQL을 자바 코드에 작성할 때 더 이상 문자열 더하기(+)와 탈출 문자(\n, \")로 고통받지 않아도 됨

 

[코드 예시: JSON 쿼리]

// Java 8: 읽기 힘들고 수정하기 어려움
String json8 = "{\n" +
               "  \"name\": \"Gemini\",\n" +
               "  \"version\": \"21\"\n" +
               "}";

// Java 21: 실제 데이터 모습 그대로 작성
String json21 = """
    {
      "name": "Gemini",
      "version": "21"
    }
    """;

 

4. 실무 대응 전략

  • Jakarta EE 전환 : Spring Boot 3.0(Java 17+)부터는 javax.* 패키지를 더 이상 지원하지 않는다.
    • javax.persistence.* -> jakarta.persistence.*
    • javax.servlet.* -> jakarta.servlet.*
    • 단순 텍스트 치환이 아닌, 설정 파일 이슈가 있으므로 검토 필요
  • G1 GC 최적화 : Java 8의 기본 GC인 Parallel GC는 처리량 중심이다. Java 21의 기본 G1 GC는 응답 시간 조절에 최적화 되어있음. 메모리 설정(-Xms, -Xmx)외에도 GC옵션이 많이 변했으므로 부하 테스트가 필수다
  • 의존성(Library)의 호환성 : 
    • Lombok: 최소 1.18.30 이상 권장
    • QueryDSL: 5.0 이상 필수 및 jakarta 패키지 설정 확인.
    • Hibernate: 6.x 버전으로 업그레이드 되면서 Dialect 설정 방식이 변함
  • Spring Boot 3.2+ 필수 : Java 21의 가상 스레드를 온전히 지원하려면 최소 Spring Boot 3.2이상을 써야함

  • 설정 한 줄로 성능 최적화: 가상 스레드를 사용하기 위해 복잡한 빈 설정 대신, application.yml에 설정 한 줄만 추가하면 톰캣이 가상 스레드 기반으로 동작함
spring:
  threads:
    virtual:
      enabled: true

 

  • GraalVM Native Image 지원: SpringBoot 3부터는 JVM 없이 실행 가능한 네이티브 이미지를 공식 지원한다. 시작 속도가 0.1초대로 줄어들어 Serverless(AWS Lamda 등) 환경에서 Java8 대비 압도적인 우위를 점한다.
  • Gradle 버전 업그레이드: Java21을 지원하려면 Gradle 8.5 이상이 필수임 (현재 7.6.4)
    Java 8시절의 compile, testCompile같은 문법은 이미 제거되었으므로 implementation, api로 완전히 전환해야 함

 

5. 이 외 기타

  • Sequenced Collections (Java 21):
    List, Set의 마지막 요소를 가져오기 위해 list.get(list.size() - 1) 대신 list.getFirst(), list.getLast() 사용 가능
  • collect(Collectors.toList()) -> .toList()

 

 

 

 

 

 

 

 

 

 

 

728x90
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2026/02   »
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
글 보관함
250x250