dev-sohee 님의 블로그

Java 8, Java 11, Java 17 뭐가 달라졌는지 알고 사용하자 본문

java

Java 8, Java 11, Java 17 뭐가 달라졌는지 알고 사용하자

dev-sohee 2024. 7. 28. 15:06

세상의 모든 프로그래밍 언어가 그렇듯 자바도 완벽하지는 않습니다. 그래서 자바는 개발자의 편의 및 성능 향사을 위해 지속적으로 업그레이드 되고 있습니다. 

이 글에서는 자바의 다양한 버전 중 Java 8, Java11, Java17에 대해 알아보겠습니다.

* Java 8
* Java 11
* Java 17

 

그 많은 버전 중에서 특별히 3가지를 선택한 이유는 바로 8, 11, 17이 LTS 버전이기 때문입니다.

LTS(Long Term Support)는 오랜 기간 지원하는 특별한 버전의 에디션이며

출시 이후 8년간 보안 업데이트와 버그 수정을 지원해주기 때문에 대부분 LTS 버전을 사용합니다.

출처_https://www.java.com/releases/

 

# Java 8

  • 오라클이 자바 인수 후 출시한 첫 번째 LTS 버전
  • 32bit를 지원하는 마지막 공식 Java 버전
  • Oracle JDK(Oracle사에서 지원하는 유료 버전) , Open JDK(오픈소스 기반의 무료)로 나뉨
  • 새로운 날짜와 시간 API(LocalDateTime 등)
  • 람다식(Lambda), Stream API
  • PermGen 영역 삭제
  • Static Link JNI Library

 

# Java 11

  • Oracle JDK와 Open JDK 통합
  • Oracle JDK가 구독형 유료 모델로 전환
  • 람다 지역 변수 사용법 변경
  • Third Party JDK로의 이전 필요
  • HTTP 클라이언트 표준화 기능

Java 11에서는 람다 표현식 내에서 var 키워드를 사용하여 지역 변수를 선언할 수 있습니다.
이는 람다 표현식의 파라미터에만 적용되며, 이를 통해 코드의 가독성이 높아지고 유지보수가 쉬워집니다.

//Java 11 이전(명시적 타입 사용) 예제 코드
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class LambdaExample {
       public static void main(String[] args) {
              List<String> names = Stream.of("Alice", "Bob", "Charlie")
                     .filter((String name) -> name.length() > 3)
                     .collect(Collectors.toList());
              names.forEach(System.out::println);
        }
}

// Java 11 이후(var 사용) 예제 코드
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class LambdaExample {
       public static void main(String[] args) {
              List<String> names = Stream.of("Alice", "Bob", "Charlie")
                     .filter((var name) -> name.length() > 3)
                     .collect(Collectors.toList());
              names.forEach(System.out::println);
       }
}

 

Java 11 의 HTTP 클라이언트 표준화 기능은 새로운 java.net.http 패키지를 통해 제공됩니다. 이는 이전에 존재하던 HttpURLConnection을 대체하고, 다음과 같은 기능을 표준화하여 제공합니다.

1. 동기 및 비동기 요청 지원: 동기식 및 비동기식으로 HTTP 요청을 처리할 수 있습니다.

2. HTTP/2 지원: HTTP/1.1뿐만 아니라 더 효율적인 HTTP/2 프로토콜을 지원합니다.

3. 빌더 패턴: 요청을 구성할 때 가독성과 사용성을 높이는 빌더 패턴을 제공합니다.

4. WebSocket 지원: WebSocket 프로토콜을 통한 실시간 양방향 통신을 지원합니다.

이러한 표준화된 API를 통해 HTTP 요청과 응답을 보다 간편하고 일관되게 처리할 수 있습니다.

 

 

# Java 17

  • 가장 최신 LTS 버전
  • 봉인 클래스(Sealed Class) 정식 추가
  • 패턴 매칭 프리뷰 단계
  • Incubator (Foreign Function & Memory API)
  • 애플 M1 및 이후 프로세서 탑재 제품군에 대한 정식 지원
  • 난수 생성 API 추가

Sealed Class는 클래스 상속을 제한하는 데 사용됩니다.

이를 통해 특정 클래스만 상속을 허용하거나 특정 서브클래스만 만들 수 있게 할 수 있습니다.

Sealed Class는 sealed, non-sealed, final 키워드를 사용하여 정의됩니다.

//Sealed Class 예제 코드
//Shape.java
public sealed class Shape permits Circle, Rectangle{
       //Shape 클래스는 Circle, Rectangle만 상속할 수 있음
}
// Circle.java
public final class Circle extends Shape {
       //Circle은 Shape의 서브클래스이며 더 이상 상속할 수 없음
       private double radius;
       public Circle(double radius) {
              this.radius = radius;
       }
       public double getRadius() {
              return radius;
       }
}
//Rectangle.java
public non-sealed class Rectangle extends Shape {
       //Rectangle은 Shape의 서브클래스이지만 non-sealed이므로 다른 클래스가 이를 상속할 수 있음
       private double length;
       private double width;
       public Rectangle(double length, double width) {
              this.length = length;
              this.width = width; }
       public double getLength() {
              return length;
       }
       public double getWidth() {
              return width;
       }
}
//난수 생성 API 메소드명
nextInt(): int 범위의 난수를 생성
nextInt(int bound): 0(포함)에서 주어진 경계(bound)(제외)까지의 난수를 생성
nextDouble(): 0.0(포함)에서 1.0(포함)까지의 난수를 생성
nextFloat(): 0.0(포함)에서 1.0(포함)까지의 난수를 생성
nextLong(): long 범위의 난수를 생성

 

출처_https://newrelic.com/kr/resources/report/2023-state-of-the-java-ecosystem
출처_https://newrelic.com/kr/resources/report/2023-state-of-the-java-ecosystem

 

 

현재 애플리케이션의 56% 이상이 운영 환경에서 Java 11을 사용하고 있습니다. 그 다음으로 많이 사용되는 버전은 약 33%를 차지한 Java 8입니다. 가장 최신 LTS 버전인 Java 17사용률은 9% 이상으로 2022년 1% 미만에서 430%나 성장했습니다. Java 8이 2014년에 등장한 다소 오래된 버전임에도 여전히 많이 사용되는 이유는 다음과 같습니다.

1. 발표된 LTS 버전 중 가장 오랜 Support를 보장

: Oracle은 JDK8이 현재까지 나온 버전 중 가장 오랜 기간 지원될 버전이라고 발표하였습니다.

2. 기존 서비스와의 호환

현재 국내에서 개발된 프로젝트는 대다수 Java 8로 개발되어 운영하고있는 상황입니다. 그렇기에 기존 프레임워크 또는 제품들과의 호환성을 유지하고 안정적으로 운영하기 위해 이후 연관된 프로젝트들 또한 JDK 8에서 벗어나지 않고 있습니다.

 

그렇다면, Java 17을 사용하는 이유에는 어떤 것들이 있을까요?

1. Java Support 기간이 길다.

: 현재까지 발표로는 8버전의 지원 기간이 17버전보다 상대적으로 조금 더 긴 게 사실입니다. 그러나, 17버전의 지원 기간이 절대적으로 짧다고 할 수는 없습니다. 

2. 신규 버전을 위한 대비

: 현재 사용 중인 버전의 지원 종료일이 도래하여 다른 LTS 버전을 찾아야 할 시점에, 8버전에서 바로 최신 버전으로 전환하는 것 보다 17버전까지의 기술 적응을 완료한 상태에서 전환 시 마이그레이션으로 인한 영향이 최소화될 것이라 생각했습니다.

3. Spring Boot 3.0 부터는 자바 17 이상을 지원 

: 현재까지 나온 스프링 공식 로드맵 상, Spring Boot 3.0부터는 JDK 17이상을 지원합니다.

 

자바의 버전별 차이점에 대해 공부하면서 

자바의 진화를 통해 소프트웨어 시장의 흐름을 알 수도 있다는 것을 느꼈습니다.

또한 업데이트된 성능과 기능을 배우는 것은 개발자로서의 역량을 확장할 수 있는 기회가 될 것 같고,

안정적인 소프트웨어 개발을 계속해서 고민하게 된다는 점에서도 큰 의미가 있는 것 같습니다.