Java17을 왜 고려해야 할까? (Java version(8~17) 별 특징 정리)

최준호·2022년 8월 4일
11

java

목록 보기
24/25
post-thumbnail

Spring boot 3.0 부터는 java17부터 지원하고 있기 때문에 새로운 스프링부트를 사용하는 분들은 무조건 17 이상을 도입해야 한다!

난 정리되어 있는 글들을 참고하여 정리한 글이기 때문에 이 보다 더 많은 내용이 추가되었을 것이다. 더 자세한 내용을 원하시는 분들은 다른 글을 참고하시면 좋을 것 같다.

😂 Java11은 왜...

Java8과 경쟁상대로 가장 많이 언급되었던 Java version은 11이였다. 그 이유는 우선 LTS였기 때문이였는데. Oracle 사에서 Java8을 사용한 레거시 프로젝트들(현재도 서비스하고 있기 때문에 새로운 기술에 계속해서 대응해줘야함!)이 너무 많음을 고려하여 Java8이 Java11보다 더 긴 지원기간을 갖게되었다.

Oracle

Java 8 : 2030년 12월까지
Java 11 : 2026년 9월까지
Java 17 : 2029년 9월까지
Red Hot

Java 8 : 2026년 5월까지
Java 11 : 2024년 10월까지
Java 17 : 미발표 (2021.8기준)

이런 이유 때문에 지금 Java11을 메인으로 프로젝트를 개발하게 된다면 26년 9월 이후에는 기술적 지원이 종료되기 때문에 Java8을 대체하는 Java version으로 11보단 17을 선호하게 되었다.

📗 Java version 별 특징

참고 java 버전별 차이 & 특징

📄 Java 8

참고 Oracle Java 8 설명

  • Lambda
  • Stream
  • interface default Method
  • Optional
  • LocalDateTime

✅ interface default Method

기존 interface는 추상 메서드만을 정의할 수 있었는데 default 선언을 통해 method를 미리 정의해둘 수 있다. 또한 정의된 default method는 상속된 class에서 오버라이딩 될 수 있다.

public interface Calculator {
	public int plus(int i, int j);
	public int multiple(int i, int j);
	default int exec(int i, int j){      //default로 선언함으로 메소드를 구현할 수 있다.
		return i + j;
	}
}

//Calculator인터페이스를 구현한 MyCalculator클래스
public class MyCalculator implements Calculator {

	@Override
	public int plus(int i, int j) {
		return i + j;
	}

	@Override
	public int multiple(int i, int j) {
		return i * j;
	}
}

public class MyCalculatorExam {
	public static void main(String[] args){
		Calculator cal = new MyCalculator();
		int value = cal.exec(5, 10);
		System.out.println(value);
	}
}

다음과 같이 default method로 선언되면 상속받은 class에서 따로 구현하지 않아도 exec method를 사용할 수 있으며 필요시 오버라이드하여 사용할 수 있다.

📄 Java 9

  • 모듈화(Jigsaw)
    참고 밸덩 jigsaw 소개
  • stream
    - takeWhile, dropWhile, iterate 등 추가
  • optional
    - ifPresentOrElse 추가
  • interface
    - private method 추가

✅ jigsaw

기존 java의 jar 패키징을 통해 모듈화를 진행하고 있지만 jar에는 문제점이 존재한다. 우선 Jar Hell이 있는데 복잡한 ClassLoader로 정의되었을 때 JVM 컴파일은 성공하지만 런타임시 ClassNotFonundException을 마주하게 된다는 것이다. 또한 Jar는 생각보다 무겁다.

그래서 jigsaw라는 새로운 모듈화를 통해 가볍고 복잡하지 않은 java 모듈 시스템을 구축한 것이다. 특히 라즈베리 파이 같은 저사양 컴퓨터에서 잘 실행될 수 있도록 구조를 잡았다고 하니 앞으로 더 범용성이 커질지도 모른다.

✅ interface private method

interface에서 private method를 사용한다는 의미는 기존 interface에서 정의된 메서드는 상속받은 class에서 구현해야했다. 아니면 상속 받은 그대로 사용하던지 하지만 private method는 interface 내부에서만 사용하며 상속 받은 class는 해당 메서드를 따로 구현할 수 없는 것이다.

public interface CustomInterface {
     
    public abstract void method1();
     
    public default void method2() {
        method4();  //private method inside default method
        method5();  //static method inside other non-static method
        System.out.println("default method");
    }
     
    public static void method3() {
        method5(); //static method inside other static method
        System.out.println("static method");
    }
     
    private void method4(){
        System.out.println("private method");
    } 
     
    private static void method5(){
        System.out.println("private static method");
    } 
}
 
public class CustomClass implements CustomInterface {
 
    @Override
    public void method1() {
        System.out.println("abstract method");
    }
     
    public static void main(String[] args){
        CustomInterface instance = new CustomClass();
        instance.method1();
        instance.method2();
        CustomInterface.method3();
    }
}

예를 들어 다음 코드를 봤을 때 method2()에서 method4()를 호출하여 사용하지만 실제 상속받은 class에서 method4()를 오버라이딩할 수 없다.

📄 Java 10

  • var 추가
  • Garbage Collector(GC) 병렬 처리 도입으로 인한 성능 향상
  • JVM heap 영역을 시스템 메모리가 아닌 다른 종류의 메모리에도 할당 가능

✅ var

// Java 10 이전
String name = "juno";

// Java 10 이후
var name = "juno";
var num = 1;

📄 Java 11

  • LTS
  • Oracle JDK와 OpenJDK 통합
  • Oracle JDK가 구독형 유료 모델로 전환
  • Lambda에 var 사용 가능
  • Java 10부터 Java 소스 파일 을 먼저 컴파일 하지 않고도 실행할 수 있다. 스크립팅을 향한 한 걸음
    - 이전 java는 소스를 컴파일하여 class로 뽑은 후 class를 실행했는데 java를 통해 바로 실행할 수 있게 되었다.

📄 Java 12

  • 유니코드 11 지원
  • switch문 확장

✅ 확장된 switch 문

//java 12 이전
String time;
switch (weekday) {
	case MONDAY:
	case FRIDAY:
		time = "10:00-18:00";
		break;
	case TUESDAY:
	case THURSDAY:
		time = "10:00-14:00";
		break;
	default:
		time = "휴일";
}
//java12 이후
String time = switch (weekday) {
	case MONDAY, FRIDAY -> "10:00-18:00";
	case TUESDAY, THURSDAY -> "10:00-14:00";
	default -> "휴일";
};

📄 Java 13

  • 유니코드 12.1 지원
  • switch 개선
  • Multi line String

✅ 개선된 switch

boolean result = switch (status) {
    case SUBSCRIBER -> true;
    case FREE_TRIAL -> false;
    default -> throw new IllegalArgumentException(*"something is murky!"*);
};

✅ 개선된 multi line string

//Java 13 이전
String htmlBeforeJava13 = *"<html>\n"* +
              *"    <body>\n"* +
              *"        <p>Hello, world</p>\n"* +
              *"    </body>\n"* +
              *"</html>\n"*;
//Java 13 이후
String htmlWithJava13 = *"""
              <html>
                  <body>
                      <p>Hello, world</p>
                  </body>
              </html>
              """*;

📄 Java 14

  • switch 표준화
  • instanceof 개선
  • recode 선언 기능 추가
  • NullPointerException 개선

✅ switch 표준화

int numLetters = switch (day) {
    case MONDAY, FRIDAY, SUNDAY -> 6;
    case TUESDAY                -> 7;
    default      -> {
      String s = day.toString();
      int result = s.length();
      yield result;
    }
};

yield는 return이라고 생각하면 쉽다.

✅ instanceof 개선

//Java 14 이전
if (obj instanceof String) {
    String s = (String) obj;
}

이전에는 obj를 캐스팅하는 것이 필요했지만

if (obj instanceof String s) {
    System.out.println(s.contains(*"hello"*));
}

다음과 같이 개선되었다.

✅ recode 선언

// Java 14 이전
final class Point {
    public final int x;
    public final int y;

    public Point(int x, int y) {
        this.x = x;
        this.y = y;
    }
}

Java 14 이전에는 다음과 같이 선언 시 equals/hashcode, toString 잠재적으로 포함되었다.

// Java 14 이후
record Point(int x, int y) { }

recode를 통해서 간단하게 선언할 수 있게 되었다.

✅ NullPointerException 개선

author.age = 35;
---
Exception in thread *"main"* java.lang.NullPointerException:
     Cannot assign field *"age"* because *"author"* is null

어떤 변수가 null인지 설명한다.

📄 Java 15

  • 스케일링 가능한 낮은 지연의 가비지 컬렉터 추가(ZGC)
  • Sealed Classes
  • Nashorn JavaScript Engine 제거
    - java에서 javaScript를 실행할 수 있었던 Engine

✅ Sealed Classes

한글로 직역하면 봉인된 클래스로 Java에서 자주 사용하던 상속을 제한할 수 있다.

public sealed interface SafetyBelt permits Car, Truck {
    String belt();
}

다음과 같이 SfatetyBelt 안전벨트를 선언해놓자.

public final class Car implements SafetyBelt{

    @Override
    public String belt() {
        // TODO Auto-generated method stub
        return null;
    }
    
}
public final class Truck implements SafetyBelt{

    @Override
    public String belt() {
        // TODO Auto-generated method stub
        return null;
    }
    
}

다음과 같이 안전벨트는 Car와 Truck에서 사용할 수 있도록 허용했고 실제 상속받아서 belt mehtod를 구현한다.
상속받은 class는 추가 확장을 방지하기 위해 final로 선언한다.

다음과 같이 다른 class에서 해당 class를 상속하지 못하도록 막아버린다.

그럼 여기서 만약 오토바이 Vehicle class에 안전벨트를 구현하려고 하면 어떻게 될까?

당연하게도 허용되지 않은 class는 해당 인터페이스를 상속받을 수 없다.

인터페이스 이외에 abstract class에서도 사용할 수 있다.

public abstract sealed class Vehicle permits Car, Truck {
	String belt();
}

📄 Java 16

  • Unix-Domain Socket Channels 사용 가능 (Mac 및 Windows(10+)에도 지원)

📄 Java 17

  • Java 11 이후 새로운 LTS
  • Pattern Matching for switch
  • Sealed Classes (Finalized)
    - Java 15에서 제공되었던 Sealed Classes 기능 완료
  • Foreign Function & Memory API
    - Java Native Interface(JNI)를 대체
  • Deprecating the Security Manager
    - Java 1.0 이후로 보안 관리자가 있었는데 현재 사용되지 않으므로 제거될 예정

✅ Pattern Matching for switch

public String test(Object obj) {

    return switch(obj) {
      case Integer i -> *"An integer"*;
      case String s -> *"A string"*;
      case Cat c -> *"A Cat"*;
      default -> *"I don't know what it is"*;
    };
}

이제 객체를 전달하여 기능을 전환하고 특정 유형을 확인할 수 있다.

👏 Java Version을 정리하며

오라클에는 Switch를 사랑하는 개발자가 있는것 같다. 하지만 Swtich가 점점 개선되어짐을 눈으로 보니 나중에 코드에 직접 적용해보면 생각보다 깔끔한 결과를 볼 수 있을거 같은 생각이 든다.

또한 Java에서 그동안 지원이 잘 안된다고 생각하던 부분인 JNI의 방향성이 달라짐에 따라 추후에 Java를 통해 컴퓨터 내부적으로 더 많은 작업을 실행할 수 있을 것 같다.

그 외에 jigsaw나 JVM, GC의 개선들을 통해 더 가볍고 더 빠르며 요즘 대세인 스트립트 언어의 방향성을 잡아가는 것 같기도 하다.

profile
코딩을 깔끔하게 하고 싶어하는 초보 개발자 (편하게 글을 쓰기위해 반말체를 사용하고 있습니다! 양해 부탁드려요!) 현재 KakaoVX 근무중입니다!

3개의 댓글

comment-user-thumbnail
2023년 2월 20일

안녕하세요 잘 봤습니다!
맨 마지막 오타가 있는것 같아요!
Vserion -> Version 인 것 같습니다!

양질의 자료 정리 감사합니다!

1개의 답글
comment-user-thumbnail
2023년 10월 21일

멋지십니다 ! 좋은 글 잘 보고 갑니다.

답글 달기