ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Java 9. 주요 변경 내용 (1)
    BackEnd/Java 2024. 12. 3. 22:00
    반응형

    try-with-resources 확장

      try-with-resources는 Java 7에서 추가된 기능으로 개발자가 직접 닫아줘야 하는 자원을 try() 안에 선언하면, try 로직이 끝난 후 자동으로 해당 자원을 닫아주는 것입니다. 자동으로 해당 자원을 닫아주기 위해서는 AutoCloseable을 구현하고 있어야 합니다.

     

    • Java 7 이전 코드
    Resource resource = new Resource();
    try {
      // 작업
    } finally {
      resource.close();
    }

     

    • Java 7 이후 코드
    try (Resource resource = new Resource()) {
      // 작업
    }

     

      Java 7의 try-with-resources의 경우, try() 밖에서 만든 자원을 닫을 수는 없습니다.

    Resource r1 = new Resource("r1");
    try (
      r1; // Compile Error !!
      Resource r2 = new Resource("r2")
    ) {
      // Logic
    }

     

      Java 9에서는 이를 개선하여 try 바깥의 final 변수 or 사실상 final인 변수(한 번 선언된 후 변경이 되지 않은)도 자동으로 자원을 닫아줍니다.

    Resource r1 = new Resource("r1");
    final Resource r2 = new Resource("r2");
    try (r1; r2) {}

     

    @SafeVarargs 어노테이션 확장

      @SafeVarargs는 Java 7에서 도입된 어노테이션으로, 제네릭 가변인수(varargs) 메소드의 타입 안전성을 보장하는 데 사용됩니다. Java 9 이전에는 @SafeVarargs 어노테이션을 final 메소드, static 메소드, 생성자에만 사용할 수 있었습니다. Java 9부터는 private 메소드에도 해당 어노테이션을 사용할 수 있게 되었습니다.

     

      가변인수(varargs)란 메소드를 호출할 때 매개변수의 개수를 자유롭게 넣을 수 있는 것으로, 내부적으로 해당 값들이 담겨 있는 배열이 생성됩니다.

    public static int sum(int... nums) {
      return Arrays.stream(nums).sum();
    }

     

      제네릭 함수에서 가변인수를 사용하면 안전하지 않을 수 있다는 경고가 발생합니다. @SafeVarargs를 사용하면 메소드 호출 시 발생하는 경고를 억제할 수 있어, 코드의 가독성을 높이고 불필요한 경고를 제거할 수 있습니다.

    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    
    public class Main {
      
      @SafeVarargs
      public static <T> List<T> flatten(List<T>... lists) {
        List<T> result = new ArrayList<>();
        for (List<T> list : lists) {
          result.addAll(list);
        }
        return result;
      }
      
      public static void main(String[] args) {
        List<Integer> list1 = Arrays.asList(1, 2, 3);
        List<Integer> list2 = Arrays.asList(4, 5);
        List<Integer> result = flatten(list1, list2);
        System.out.println(result);
      }
    }

     

    익명 inner class + diamond syntax

      Java 9부터는 내부 클래스를 익명 클래스로 만들 때 diamond syntax 사용이 가능해졌습니다. diamond syntax란 제네릭 클래스를 인스턴스화 할 때 우항(오른쪽)의 타입을 생략할 수 있는 것입니다.

    // 타입을 생략하지 않음
    List<Integer> numbers1 = new ArrayList<Integer>();
    
    // 타입을 생략함 (diamond syntax)
    List<Integer> numbers2 = new ArrayList<>();

     

      내부 클래스는 외부 참조를 할 수 있는 내부 클래스와 외부 참조를 할 수 없는 내부 클래스가 있습니다. 외부 참조가 있으면 메모리 관리가 어렵고, 직렬화 표준도 없기 때문에 외부 참조가 없는 내부 클래스가 권장됩니다.

    public class Main {
      // 외부 (Main) 참조를 할 수 있는 내부 클래스
      public class ReferenceClass { }
      
      // 외부 (Main) 참조를 할 수 없는 내부 클래스
      public static class NoReferenceClass { }
    }

     

      다음은 Java 9부터 내부 클래스를 익명 클래스로 만들 때 diamond syntax를 적용한 코드입니다.

    public class Main {
    
      public static void main(String[] args) {
        InnerClass<Integer> ic = new InnerClass<>(3) { // diamond syntax
        };
        int _abc = 3;
      }
      
      public static class InnerClass<T> {
        private final T t;
        public InnerClass(T t) {
          this.t = t;
        }
      }
    }

     

    인터페이스 + private 메소드

      Java 8부터는 인터페이스에 default 메소드를 구현할 수 있게 되었습니다. 그러나 default 메소드를 구현 하다 보니 로직이 겹치는 코드가 발생하기 시작하였습니다. Java 9에서는 중복된 코드를 제거하고 재사용성 향상을 위해 인터페이스에도 private 메소드를 사용 가능하게 되었습니다.

    public interface PaymentProcessor {
        
        default void processPayment(double amount) {
            if (validateAmount(amount)) {
                System.out.println("Processing payment of $" + amount);
                sendConfirmation();
            } else {
                System.out.println("Invalid payment amount");
            }
        }
        
        default void refundPayment(double amount) {
            if (validateAmount(amount)) {
                System.out.println("Refunding payment of $" + amount);
                sendConfirmation();
            } else {
                System.out.println("Invalid refund amount");
            }
        }
        
        // Private helper method
        private boolean validateAmount(double amount) {
            return amount > 0;
        }
        
        // Private helper method
        private void sendConfirmation() {
            System.out.println("Sending confirmation email...");
        }
        
        // Static private method
        private static void logTransaction(String type, double amount) {
            System.out.println("Logging " + type + " transaction: $" + amount);
        }
        
        // Public static method that uses private static method
        static void auditPayment(double amount) {
            logTransaction("payment", amount);
        }
    }

     

    underscore 네이밍 불가능

      Java 9에서는 언더스코어(_)를 변수 이름으로 사용하는 것이 불가능하게 되었습니다. 이는 언더스코어가 Java 9부터 예약된 키워드로 지정되었기 때문입니다. 해당 변경은 언더스코어를 향후 Java 버전에서 특별한 의미를 가진 키워드로 사용하기 위한 준비 단계입니다.

    반응형

    'BackEnd > Java' 카테고리의 다른 글

    Java 10. 주요 변경 내용  (1) 2024.12.05
    Java 9. 주요 변경 내용 (2)  (0) 2024.12.04
    Java 9. JPMS  (0) 2024.12.02
    Java8. parallelSort  (0) 2022.01.25
    Java8. CompletableFuture  (0) 2022.01.23

    댓글

Designed by Tistory.