본문 바로가기

Study/Java

JDK 13 New Features

반응형

JDK의 버전별 변경 사항은 이곳을 참고하세요.

Spec

Java SE 13 Platform JSR 388에 정의된 바와 같이 JSR 388 구현이 목표

실제 Spec은 Final Release Specification 문서를 참고해야 함

Final Release Specification Feature Summary

전체 JEP Feature 목록은 OpenJDK의 JDK 13 문서로 확인할 수 있다.

Component Feature
specification / language Switch Expressions (Preview)
specification / language Text Block (Preview)

Switch Expressions (Preview)

Switch Expression은 JDK 12부터 preview 기능으로 제공되었다.

관련한 기능은 JDK 12 New Features를 참고하면 된다.

JDK 12의 기능 이후 피드백을 반영하였는데 Yielding a value 가 추가되었다.

Yielding a value는 switch가 표현식이 가능하게 되면서 반환 값 처리에 대해 명시를 위해 제공되는 기능이다.

"case L ->" 의 오른쪽 표현식이 블록으로 처리되는 경우 반환하는 값이 어떤 것인지 지정을 할 수 있게 되었다.

int j = switch (day) {
    case MONDAY  -> 0;
    case TUESDAY -> 1;
    default      -> {
        int k = day.toString().length();
        int result = f(k);
        yield result;
    }
};

이는 기존 표현식 switch 구문에도 사용할 수 있다.

int result = switch (s) {
    case "Foo": 
        yield 1;
    case "Bar":
        yield 2;
    default:
        System.out.println("Neither Foo nor Bar, hmmm...");
        yield 0;
};

Text Block (Preview)

여러줄에 걸친 텍스트를 좀더 편하게 사용할 수 있게 되었다.

HTML의 예시

기존의 경우

String html = "<html>\n" +
              "    <body>\n" +
              "        <p>Hello, world</p>\n" +
              "    </body>\n" +
              "</html>\n";

text block을 사용하는 경우

String html = """
              <html>
                  <body>
                      <p>Hello, world</p>
                  </body>
              </html>
              """;

SQL의 예시

기존의 경우

String query = "SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB`\n" +
               "WHERE `CITY` = 'INDIANAPOLIS'\n" +
               "ORDER BY `EMP_ID`, `LAST_NAME`;\n";

text block을 사용하는 경우

String query = """
               SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB`
               WHERE `CITY` = 'INDIANAPOLIS'
               ORDER BY `EMP_ID`, `LAST_NAME`;
               """;

Polyglot language의 예시

기존의 경우

ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
Object obj = engine.eval("function hello() {\n" +
                         "    print('\"Hello, world\"');\n" +
                         "}\n" +
                         "\n" +
                         "hello();\n");

text block을 사용하는 경우

ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
Object obj = engine.eval("""
                         function hello() {
                             print('"Hello, world"');
                         }
                         
                         hello();
                         """);

공백 처리

java 코드는 보통 들여쓰기가 이루어지기 때문에 text block을 들여쓰기 한 경우의 실제 출력에서는 해당 들여쓰기 부분을 제거하는 처리도 해준다.

String html = """
..............<html>
..............    <body>
..............        <p>Hello, world</p>
..............    </body>
..............</html>
..............""";

위 예시에서 앞 쪽의 ... 으로 표현된 공백은 실제 출력시 제거된 상태로 표시된다.

text block을 닫는 마지막 라인의 """ 의 앞 공백만큼이 제거될 대상 공백이 된다.

텍스트 블록의 연결

기존 String과 연결은 다음처럼 할 수 있다.

String code = "public void print(Object o) {" +
              """
                  System.out.println(Objects.toString(o));
              }
              """;

 

만약 다음과 같은 text block이 있다면 (위 예시의 연결을 합한 단일 text block임)

String code = """
              public void print(Object o) {
                  System.out.println(Objects.toString(o));
              }
              """;

해당 text block내 java code 문법에서 매개 변수의 Object 부분을 변수 처리 하고자 하는 경우 다음처럼 사용할 수 있다.

(문서 상에는 연결을 사용하면 후행 코드가 포함된 텍스트 블록이 """가 시작된 위치에서 새 줄이 시작되기 때문에 다음과 같은 모양이 된다고 하는 듯 하다. - IDE의 자동 들여쓰기 처리 이슈인 듯?)

String code = """
              public void print(""" + type + """
                                                 o) {
                  System.out.println(Objects.toString(o));
              }
              """;

공백은 수동으로 제거할 수 있긴하지만 가독성이 떨어진다.

String code = """
              public void print(""" + type + """
               o) {
                  System.out.println(Objects.toString(o));
              }
              """;

이에 대한 대안으로 String::replace 또는 String::format 을 사용할 수 있다.

String code = """
              public void print($type o) {
                  System.out.println(Objects.toString(o));
              }
              """.replace("$type", type);
String code = String.format("""
              public void print(%s o) {
                  System.out.println(Objects.toString(o));
              }
              """, type);

또 다른 대안은 String::formatted를 사용하는 경우이다.

String source = """
                public void print(%s object) {
                    System.out.println(Objects.toString(object));
                }
                """.formatted(type);

추가 메서드

text block 을 지원하기 위해 아래 메서드가 추가된다.

String::stripIndent() : 텍스트 블록 내용에서 우발적인 공백을 제거하는데 사용

String::translateEscapes() : escape 시퀀스를 번역하는데 사용

String::formatted(Object... args) 텍스트 블록에서 값 대체를 단순화

반응형