개발 낙서장

JDK 17을 쓰는 이유 본문

Java

JDK 17을 쓰는 이유

권승준 2024. 5. 2. 21:14

JDK

JDK는 자바 개발 키트(Java Development Kit)로 자바 언어를 다양하게 활용할 수 있도록 여러 클래스 및 라이브러리와 컴파일러 등 자바 환경에서 돌아가는 프로그램을 개발하는데 필요한 툴을 모아놓은 소프트웨어 패키지이다.

JDK가 없다면 우리가 너무나 당연하게 쓰고 있는 List라던지 Object라던지 래퍼 클래스 등 대부분의 클래스나 라이브러리를 직접 구현해 사용해야 하고 컴파일러가 없기 때문에 라이브러리를 직접 구현했다 하더라도 프로그램을 실행할 수가 없다.
물론 자바로 개발을 하려면 JDK는 필수적으로 설치하기에 JDK 없이 개발하는 일은 없다.

갑자기 웬 JDK?

이번 웹 개발 트랙을 시작하면서부터 JDK 17 버전을 사용해 왔는데 최종 프로젝트가 끝나 취업을 준비하는 지금까지도 '왜 굳이 17 버전을 사용했을까?'에 대한 고민을 하지 않았었다.

개발자로서 말이 안 되는 부분이다. 어떤 클래스 하나를 사용하더라도 왜 사용했는지 이유를 알고 있어야 하는데 자바의 버전에 대해 고민하지 않는 건 말이 안 된다.

그래서 늦었지만 지금이라도 자바의 대표적인 버전이 어떤 것이 있고 그중에서 왜 17을 사용했는가에 대한 고찰을 해보았다.

LTS

자바 뿐만 아니라 유니티도 그렇고 개발 툴에는 각각 버전이 있으며 그중 LTS 버전이 존재한다.

LTS란 Long Term Support의 약자로 오랫동안 지원해주는 버전을 말한다. 어느 정도냐면 자바 8이 LTS 버전 중 하나인데 14년에 출시하여 30년까지 지원한다고 한다.

LTS 버전은 많은 기업들과 개발자에게 인기가 좋을 수밖에 없는데 기본적으로 안정성이 좋고 오랜 기간 동안 기술적인 지원을 해주기에 서비스 중간에 발생하는 프로그래밍적 버그에 대해 유연하게 대처할 수 있다.
또한 버전을 업그레이드하는 비용 또한 만만치 않기에 LTS를 사용하여 버전 교체도 여유를 갖고 준비할 수 있다.

현재 자바의 LTS 버전으로는 자바 8, 자바 11, 자바 17이 있다.

버전 만료 기간
Java 8 2030년 12월
Java 11 2026년 9월
Java 17 2029년 9월

현재 자바 22 버전까지 나왔지만 LTS가 아닌 버전들은 새로운 기술에 중점을 두고 출시한 버전이기에 보다 안정성이 떨어지고 지원 기간 또한 짧아 대부분의 기업들이 LTS를 사용하고 있고 그중에서도 자바 8, 자바 17을 많이 사용한다고 한다.

이유는 당연하게도 자바 11은 자바 8보다 늦게 나왔음에도 만료 기간이 4년이나 짧고 기존에 수많은 회사들과 개발자들이 자바 8을 사용하고 있었기에 커뮤니티가 잘 구성돼있고 모듈이나 라이브러리 간 안정성과 호환성이 좋기 때문이라고 한다.
결국 가장 큰 이유는 마이그레이션을 하는 비용과 추후 유지 보수에서 발생하는 비용이 비싸기 때문일 것이다.

이미지 출처 : JetBrains

실제로 JetBrains에서 조사한 결과 여전히 많은 사람들이 자바 8을 사용하고 그 다음으로 자바 17을 많이 사용한다고 한다. 물론 자바 11도 LTS이기에 상당수가 사용하긴 하지만 26년에 지원이 종료되기에 비율은 점점 줄어들 것이다.

어쨌든 그런 이유에서 오늘은 자바 8과 자바 17의 특징들을 살펴보고 그 중에서 자바 17을 선택한 이유가 무엇일까에 대해 고민해 볼 것이다.

Java 8

자바 8은 2014년 3월에 출시된 자바의 첫 LTS 버전이다. 2030년 12월까지 지원하며 현재까지 나온 버전 중 가장 오랫동안 지원하는 버전이다.

  • 람다
  • 스트림
  • LocalDateTime
  • 인터페이스 default 메소드
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
names.forEach(name -> System.out.println(name));

람다는 메소드를 간단히 표현하여 코드의 가독성을 높여주는 표현식이다.
원래대로라면 name 변수를 받아 출력하는 등의 로직을 처리하는 함수를 별도로 구현해야 하지만 람다 표현식을 사용하면 한 줄로 표현할 수 있어 코드의 간결함과 가독성이 높아진다.

List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
long count = names.stream()
                  .filter(name -> name.length() > 3)
                  .count();
System.out.println("Length > 3: " + count);

스트림은 Collection, 배열 등에 대한 처리들을 메소드화하여 사용할 수 있는 기능이다.
객체 매핑, 변환, 수정 등 복잡한 로직을 메소드로 처리할 수 있으며 병렬 처리를 지원해 성능 또한 크게 향상할 수 있다.

public interface Vehicle {
    default void printInfo() {
        System.out.println("This is a vehicle.");
    }
}

public class Car implements Vehicle {
    public static void main(String[] args) {
        Car car = new Car();
        car.printInfo();
    }
}

기존에 인터페이스는 구현할 메소드를 선언만 해놓고 구현체에서 해당 로직들을 구현해야 했는데 자바 8 부터는 default 메소드를 지원해 인터페이스에서도 공통 메소드를 구현할 수 있다.
또한 구현체에서 오버라이딩 또한 가능하기에 기존보다 코드 재사용성, 확장성이 향상된 기능이다.

Java 17

자바 17은 2021년 9월에 출시됐으며 29년 9월까지 기술적 지원을 하고 현재까지 LTS 중 가장 최신 버전이다.

  • 텍스트 블록
  • 로컬 변수 타입 추론(var)
  • Switch 개선
  • record 클래스
        String ksj = """
                {
                    "name": "권승준",
                    "birth": 1997,
                    "gender": "male",
                    "marital": false
                }
                """;

"""를 통해 문자열을 보다 가독성 있게 표현할 수 있다.
위와 같이 Json 문자열을 표현할 때 사용할 수도 있고 여러 줄로 이루어진 문장 혹은 문단을 표현할 때도 편하게 사용할 수 있다.

        var name = "권승준";
        var birth = 1997;
        var marital = false;

변수 선언 시 타입 추론을 이용해 타입을 명시하지 않고도 변수를 선언하고 사용할 수 있게 해 준다.
컴파일 단계에서 변수를 추론하기에 성능에 영향은 없지만 무분별한 사용은 코드 가독성을 떨어뜨리므로 적절한 사용이 필요하다.

        int month = 2;
        int days = switch (month) {
            case 1, 3, 5, 7, 8, 10, 12 -> 31;
            case 4, 6, 9, 11 -> 30;
            case 2 -> {
                System.out.println("2월은 28일!");
                yield 28;
            }
            default -> throw new IllegalArgumentException("Invalid month: " + month);
        };
        
        /*
         * Output :
         * 2월은 28일!
         * 28
         */
        System.out.println(days);

기존 일일이 case와 break를 작성해야 했던 방식과 다르게 람다식을 지원하고 switch 문을 직접 반환해 변수로 사용할 수 있으며 yield 리턴 방식으로 추가적인 로직을 구현할 수 있다.

    public record Vehicle(String name, int power) {
    }

    public static void main(String[] args) {
        Vehicle car = new Vehicle("Genesis", 3000);

        // Output : Genesis
        System.out.println(car.name);

        // Output : 3000
        System.out.println(car.power);

        // Output : false
        System.out.println(car.equals(new Vehicle("Genesis", 2000)));

        // Output : Vehicle[name=Genesis, power=3000]
        System.out.println(car);
    }

record 클래스를 지원해 줌으로써 정적 데이터를 간단하게 정의하고 사용할 수 있다.
record 클래스에 선언된 변수들은 private final 형식으로 불변하며 생성자 및 getter, equals, hashCode, toString 등을 제공해 준다.

그래서 결론은?

사실 지금까지는 JDK 17을 쓰니까 썼다. 그냥 흐름에 맞춰서 사람들이 많이 쓴다더라~ 강의에서 17 버전으로 맞추라더라~ 해서 썼었다.

근데 이번 기회를 통해 17 버전이 과거 8이나 11 버전에 비해 굉장히 기능도 다양하고 장점도 많은 버전이라는 것을 알게 되었다.
특히 향상된 Switch 문이 인상적이었다. 나도 Switch 문 사용이 불편해서 기피하는 경향이 있었는데 앞으로는 종종 사용할 것 같다.

결국 자바 17을 사용한 이유는 LTS 중 가장 최신 버전이면서 오랜 기간 동안 지원해 주며 과거 버전에 비해 기능들이 많이 개선되었기 때문이고 현재 많은 서비스에서 17 버전을 사용 중이고 앞으로 나올 LTS 버전에 대한 마이그레이션 또한 다른 LTS 보다 비교적 쉬울 것이기에 사용한다고 할 수 있을 것 같다.

'Java' 카테고리의 다른 글

[Spring] @RequestPart 테스트 HttpMediaTypeNotSupportedException  (0) 2024.05.17
Spring + Redis Cache  (0) 2024.05.13
[Spring] WebSocket 통신  (0) 2024.03.28
[Spring] AOP로 권한 체크하기  (0) 2024.03.21
[Spring] QueryDSL 페이징  (0) 2024.03.12
Comments