파란하늘의 지식창고
Published 2019. 9. 25. 16:58
JDK 13 New Features Study/Java
반응형

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) 텍스트 블록에서 값 대체를 단순화

반응형
profile

파란하늘의 지식창고

@Bluesky_

도움이 되었다면 광고를 클릭해주세요