Spring Framework 6.0, Spring Boot 3.0 에서 Java 17 버전을 선택하여 9 버전 이후부터 업데이트 된 내용을 확인하고자 한다.
[Preparing for Spring Boot 3.0](https://spring.io/blog/2022/05/24/preparing-for-spring-boot-3-0)

Java 11(LTS) 까지의 업데이트

  • Java 9
    • Jigsaw module system 참고:Baeldung
      • 라이브러리와 규모가 큰 시스템을 모듈화하고 강력한 접근 제어를 통해 느슨한 결합, 모듈 간 결합 방지, 보안성 향상 등에 이점을 갖는다
      • JPMS(Java Platform Module System)의 일환으로 JRE를 작은 단위 모듈로 쪼개고 사용하는 모듈만 패키징하여 배포 가능(module-info.java)
    • JShell(The Java Shell (Read-Eval-Print Loop)) Tool
      • script 형태로 Main Method 없이 즉석에서 실행 가능한 도구
    • jlink(The Java Linker)
      • 최근에는 JDK만 제공하고 JRE는 제공하고 있지 않기 떄문에 필요시 jlink 기능을 사용하여 추출 가능
    • Immutable Set(of)
      Set<String> keySet = Set.of("key1", "key2", "key3")
      
    • Optional.stream()
      List<String> filteredList = listOfOptionals.stream()
                  .flatMap(Optional::stream)
                  .collect(Collectors.toList());
      
    • Interface private method 도입
      @FunctionalInterface
      public interface PrivateMethodInterface {
          private static String staticPrivate() {
              return "Static Private";
          }
          
          private String instancePrivate() {
              return "Instance Private";
          }
          
          void printPrivateMethod();
          
          default void check() {
              String result = staticPrivate();
              PrivateMethodInterface privateMethodInterface = () -> {
                  System.out.println(this.instancePrivate());
              };
          
              privateMethodInterface.printPrivateMethod();
              result = privateMethodInterface.instancePrivate();
          }
      }
      
    • New HTTP Client
      • java.net.http 패키지하에 있는 신규 API로 HTTP/2 프로토콜, 웹소켓을 지원한다 ```java HttpRequest request = HttpRequest.newBuilder() .uri(new URI(“http://localhost:8080/members”)) .GET() .build();

      HttpResponse response = HttpClient.newHttpClient() .send(request, HttpResponse.BodyHandlers.ofString()); ```

  • Java 10
    • Optional.orElseThrow
    • var 변수 선언 가능(타입 추론) 참고:Java 10 LocalVariable
      • 주의사항
        var variable1; // compile error without initializer
        var variable2 = null; // compile error is null
        public var variable3 = "Hello Java10"; // compile error non-local variable
        var lambda = (String s) -> s.length > 10; // lambda expression needs an explicit target-type //Predicate<String> filter = s -> s.length() > 10;
        var arr = {1, 2, 3}; // compile error, array initializer needs an explicit target-type
        
      • 사용 방법
        int[] arr = {1, 2, 3};
        for (var n : arr) {
            System.out.println(n);
        }
        var map = new HashMap<Integer, String>();
        
    • 불변 컬렉션 생성 메소드 추가(copyOf, toUnmodifiableSet, …)
    • Parallel Full GC for G1
      • G1GC에서 Full GC 발생 시 병렬 처리하여 성능 향상
  • Java 11
    • HTTP Client (http://openjdk.org/jeps/321)
      • non-blocking backpressure를 이용한 비동기 스트림 처리 지원 API 추가
      • HTTP2 를 구현하는 신규 클라이언트 API 제공, 기존 HttpURLConnection API 대체
    • ZGC
      • Z GarbageCollector로 stop-the-world 성능 저하 개선을 위한 목적으로 개발
        • 처리시간이 10ms 를 초과하지 않아 짧은 지연시간 보장
    • Lambda 내에서도 var 변수 사용 가능
      Stream.of(1, 2, 3, 4)
          .map((var i) -> i * 2);
          .collect(Collectors.toList());
      
      • var 를 붙이는 이유는, var 앞에 @NonNull과 같은 애노테이션을 붙일 수 있고, 컴파일러가 타입추론을 해준다.
    • Collection to Array
      List<String> list = Arrays.asList("Hello", "Java", "11");
      String[] array = list.toArray(String[]::new);
      
    • String 신규 method 추가
      • isBlank, lines, strip, stripLeading, stripTrailing, repeat 등 신규 String Method 추가

Java 17(LTS) 까지의 업데이트

  • Java 12, 13, 14
    • switch 문 개선 및 표준화(12~14)
      boolean isTodayHoliday = switch (day) {
          case "MONDAY", "TUESDAY", "WEDNESDAY", "THURSDAY", "FRIDAY" -> false;
          case "SATURDAY", "SUNDAY" -> true;
          default -> throw new IllegalArgumentException("What's a " + day);
      };
      
    • Collectors.teeing 신규 메소드(12)
      • downstream collector에 대한 copmosite 제공
        Collector<T, ?. R> teeing(Collector<? super T, ?, R1> downstream1, Collector<? super T, ?, R2> downstream2, BiFunction<? super R1, ? super R2, R> merger)
        
        double mean = Stream.of(1, 2, 3, 4)
                  .collect(Collectors.teeing(Collectors.summingDouble(i -> i), Collectors.counting()
                          , (sum, count) -> sum / count));
        
    • Pattern matching for instanceof
      Object s = "Hello World";
      // AS-IS
      if(s instanceof String) {
          String str1 = (String) s;
          System.out.println(str1);
      }
      // TO-BE
      if(s instanceof String str2) {
          System.out.println(str2);
      }
      
    • multi line string(13)
      • 텍스트 블록 기능 추가
        // AS-IS
        String JSON_STRING 
        = "{\r\n" + "\"name\" : \"Baeldung\",\r\n" + "\"website\" : \"https://www.%s.com/\"\r\n" + "}";
        // TO-BE
        String TEXT_BLOCK_JSON = """
        {
          "name" : "Baeldung",
          "website" : "https://www.%s.com/"
        }
        """;
        
    • NumberFormat 신규 method 추가(12, 14)
      • NumberFormat fmt = NumberFormat.getCompactNumberInstance(Locale.US, NumberFormat.Style.SHORT);
    • record 키워드
      • immutable 객체를 생성하는 방법 중 하나로 toString, equals, hashCode 등에 구현 자동 제공
        public record User(int id, String password) {
          public User {
              if(password.isBlank() || password.length() < 10) {
                  throw new IllegalArgumentException("Password length");
              }
          }
        };
        User user = new User(1, "password1234");
        user.id();
        user.password();
        
  • Java 15
    • CharSequence 클래스에 메소드 추가
      • isEmpty
    • TreeMap 클래스에 메소드 추가
      • putIfAbsend, computeIfAbsent, ComputeIfPresent, compute, merge
    • Sealed Class
      • 상속관계에서 부모 클래스에서 자식 클래스의 집합을 제한하여 모델링을 간소화할 수 있도록 한다
        public abstract sealed class Person permits Employee, Manager { 
          //...
        }
        
    • Hidden Class
      • Runtime에서 클래스를 생성하고 reflection을 통해 간접적으로 사용하는 프레임워크에서 사용하기 위한 것
      • Hidden Class에서는 접근 제어를 member로 정의하며 다른 class와 독립적으로 unload할 수 있다
    • ZGC 운영 환경 사용할 수 있는 준비 완료
  • Java 16
    • InvokeHandler 인터페이스에 invokeDefault default method 정의 (Proxy Instances)
      interface HelloWorld {
          default String hello() {
              return "world";
          }
      }
      
      Object proxy = Proxy.newProxyInstance(getSystemClassLoader(), new Class<?>[] { HelloWorld.class },
          (prox, method, args) -> {
              if (method.isDefault()) {
                  return InvocationHandler.invokeDefault(prox, method, args);
              }
              // ...
          }
      );
      Method method = proxy.getClass().getMethod("hello");
      assertThat(method.invoke(proxy)).isEqualTo("world");
      
    • NIO SocketChannel, ServerSocketChannel에 AF_UNIX(Unix domain sockets) 추가
    • Stream.toList() 메소드 추가
      List<String> integersAsString = Arrays.asList("1", "2", "3");
      List<Integer> ints = integersAsString.stream().map(Integer::parseInt).collect(Collectors.toList());
      List<Integer> intsEquivalent = integersAsString.stream().map(Integer::parseInt).toList();
      

       

  • Java 17
    • Sealed Class 기능 완료
      • java.lang.Class에는 아래와 같이, 2개의 새로운 메서드가 추가 되어, 어떤 클래스가 sealed되어 있는지 확인하고, 허가된 서브클래스의 리스트를 가져오는 역할을 합니다
      • Class<?>[] getPermittedSubclasses(); boolean isSealed();
    • switch 문 패턴 매칭
    • DatagramSocket이 Multicast Group에 바로 join되어 사용 가능하도록 수정
    • Foreign Function & Memory API
      • JNI 대체를 위한 것으로 모든 네이티브 라이브러리를 쉽게 사용할 수 있도록 하는 것이 목표. 자바 프로그램이 네이티브 라이브러리와 상호 작용할 수 있는 기반 제공

출처