3분만에 알게 된 신경이 쓰이는 JDK12

Java Advent Calendar 2018 14일째의 기사입니다.
JDK12가 내년 릴리스될 예정이므로, 12의 변경 내용에 대해서 일부 소개합니다.

Features



JDK12에 포함되는 JEP(JDK Enhancement Proposal)는 이하
2018/12/6 시점

89: Shenandoah: A Low-Pause-Time Garbage Collector
  (Experimental)
230: Microbenchmark Suite
325: Switch Expressions (Preview)
326 : Raw String Literals (Preview) ← JDK12에서 드롭 될지도 (2018/12/14 갱신)
334: JVM Constants API
340: One AArch64 Port, Not Two
341: Default CDS Archives
344: Abortable Mixed Collections for G1
346: Promptly Return Unused Committed Memory from G1

이 기사에서는 Java 구문에 대한 변경으로 많은 Java 프로그래머에게 영향을 미치는 두 가지
  • 325: Switch Expressions (Preview)
  • 326: Raw String Literals (Preview)

  • 에 대해 해설한다.

    JEP325: Switch Expressions (Preview)



    Project Amber의 한 사양이다. Java의 switch 구문의 표현을 조금 개선하는 것.

    지금까지의 switch 구문은, break문의 출현 순서에 의존하고 있었기 때문에 직관적이 아니고, 그것이 잠재 버그의 기초가 되어 왔다.
    //今までのswitch文
    switch (day) {
        case MONDAY:
        case FRIDAY:
        case SUNDAY:
            System.out.println(6);
            break;
        case TUESDAY:
            System.out.println(7);
            break;
        case THURSDAY:
        case SATURDAY:
            System.out.println(8);
            break;
        case WEDNESDAY:
            System.out.println(9);
            break;
    }
    

    다음은 개선된 switch 문
    //改善されたswitch文
    switch (day) {
        case MONDAY, FRIDAY, SUNDAY -> System.out.println(6);
        case TUESDAY                -> System.out.println(7);
        case THURSDAY, SATURDAY     -> System.out.println(8);
        case WEDNESDAY              -> System.out.println(9);
    }
    
  • case의 라벨을 복수 쓸 수 있습니다
  • ->에서 람다 식과 같이 쓸 수 있습니다
  • break 문이 필요하지 않습니다

  • 꽤 깔끔한

    변수에 대입 케이스



    switch 문장에서 자주 있는 케이스로 가변에 대입이 있다.
    //今までのswitch文
    int numLetters;
    switch (day) {
        case MONDAY:
        case FRIDAY:
        case SUNDAY:
            numLetters = 6;
            break;
        case TUESDAY:
            numLetters = 7;
            break;
        case THURSDAY:
        case SATURDAY:
            numLetters = 8;
            break;
        case WEDNESDAY:
            numLetters = 9;
            break;
        default:
            throw new IllegalStateException("Wat: " + day);
    }
    

    일일이 각 case내에서 대입 처리를 쓰고 있지만, 이것이 이하와 같이 쓸 수 있다.
    //改善されたswitch文
    int numLetters = switch (day) {
        case MONDAY, FRIDAY, SUNDAY -> 6;
        case TUESDAY                -> 7;
        case THURSDAY, SATURDAY     -> 8;
        case WEDNESDAY              -> 9;
    };
    

    그리고 이런 쓰기도 할 수 있다.
    int numLetters = switch (day) {
        case MONDAY, FRIDAY, SUNDAY: break 6;
        case TUESDAY:                break 7;
        case THURSDAY, SATURDAY:     break 8;
        case WEDNESDAY:              break 9;
    };
    

    오류 패턴



    몇 가지 조심

    케이스 1
    final int num = 3;
    String str = switch(num) {
        case 1 -> "one";
        case 2 -> "two";
    };
    

    이 쓰기는 컴파일 오류입니다.
    오류 메시지는 "the switch expression does not cover all possible input values"
    즉, switch의 인수가 취할 수 있는 값은 모두 switch의 조건 분기로서 커버해라! 라는 것.

    이 경우는 int의 가능한 값을 모두 case에 쓰면 해결
    대신 default를 작성하면 빌드가 성공합니다.
    final int num = 3;
    String str = switch(num) {
        case 1 -> "one";
        case 2 -> "two";
        default -> "non";
    };
    

    케이스 2
    final int num = 3;
    String str = switch(num) {
        case 1: break "one";
        case 2 -> "two";
        default -> "non";
    };
    

    이것도 컴파일 에러가 된다.
    오류 메시지는 "different case kinds used in the switch"
    쓰는 법을 통일하라! 라는 것.

    326: Raw String Literals (Preview)



    문자열 리터럴의 표현이 간단해진다.
    URL 패스나 정규 표현, 복수행 캐릭터 라인을 소스 코드내에 쓸 때, 지금까지는 일일이 이스케이프 하거나 개행 넣거나 해 생산성도 가독성도 떨어졌지만, 그런 번거로움으로부터 해방된다.

    ""(더블 쿼트)"가 아니라 ""(백쿼트)"로 문자열을 둘러싼다.

    파일 경로 예
    Runtime.getRuntime().exec("\"C:\\Program Files\\foo\" bar");
    Runtime.getRuntime().exec(`"C:\Program Files\foo" bar`);
    

    정규식의 예
    System.out.println("this".matches("\\w\\w\\w\\w"));
    System.out.println("this".matches(`\w\w\w\w`));
    

    여러 줄의 예
    String html = "<html>\n" +
                  "    <body>\n" +
                  "         <p>Hello World.</p>\n" +
                  "    </body>\n" +
                  "</html>\n";
    String html = `<html>
                        <body>
                           <p>Hello World.</p>
                       </body>
                   </html>
                  `;
    

    마지막으로



    둘 다 Preview 스테이터스이므로, 향후 변경이 들어가는 일도 있을지도 모르고, 실제의 프로덕션(업무)으로 사용할 수 있는 것은 JDK13 이후가 된다고 생각합니다. 그래서 JDK12에서는 만져 놀 정도로 즐기세요.
    그런 다음 컴파일과 런타임에 "--enable-preview"옵션을 사용하지 않으면 오류가 발생합니다.

    좋은 웹페이지 즐겨찾기