자바 14 기능

다음은 2019년 9월 17일에 Java 13이 출시된 후 6개월 주기 전통을 유지하며, Java 14가 예정된 날짜인 2020년 3월 17일에 출시될 예정입니다.

Java 14 기능

다음은 Java 14의 기능 목록입니다:

  • Switch 표현식 (표준) – JEP 361
  • instanceof를 위한 Pattern Matching (미리보기) – JEP 305
  • NullPointerExceptions 도움말 – JEP 358
  • Records (미리보기) – JEP 359
  • Text Blocks (두 번째 미리보기) – JEP 368
  • Packaging Tool (Incubator) – JEP 343
  • G1을 위한 NUMA-Aware Memory Allocation – JEP 345
  • JFR 이벤트 스트리밍 – JEP 349
  • Non-Volatile Mapped Byte Buffers – JEP 352
  • macOS에서의 ZGC – JEP 364
  • Windows에서의 ZGC – JEP 365
  • Foreign-Memory Access API (Incubator) – JEP 370

Mac OS에서의 Java 14 설치 설정

  • Java 14를 시작하려면 여기서 JDK를 다운로드하세요.
  • 다음과 같이 /Library/Java/JavaVirtualMachines에 tar 파일을 복사하고 압축을 해제하세요:
$ cd /Library/Java/JavaVirtualMachines

$ sudo cp ~/Downloads/openjdk-14_osx-x64_bin.tar.gz /Library/Java/JavaVirtualMachines

$ sudo tar xzf openjdk-14_osx-x64_bin.tar.gz

$ sudo rm openjdk-14_osx-x64_bin.tar.gz

그 후에는 텍스트 편집기를 사용하여 bash_profile을 엽니다. 저는 vim ~/.bash_profile을 사용하고 있습니다. Java14의 경로를 JAVA_HOME으로 설정하고 변경 사항을 저장하고 변경 사항을 반영하려면 source ~/.bash_profile을(를) 실행하세요.

export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk-14.jdk/Contents/Home

마지막으로, Java 14를 사용하여 프로그램을 컴파일하고 실행할 준비가 되었습니다. 새로운 Java 14 기능을 빠르게 테스트하기 위한 대화형 REPL 명령 줄 도구 인 JShell을(를) 사용할 것입니다.

Java 14에서 출시된 많은 기능이 미리보기 상태입니다. 이는 현재 완전히 작동하지만 향후 변경될 수 있다는 것을 의미합니다. 일부는 표준으로 만들어질 수 있으며 다음 릴리스 주기에서 제거될 수도 있습니다. 미리보기 기능을 테스트하려면 아래에 표시된대로 JShell 또는 Java 프로그램을 실행할 때 명시적으로 --enable-preview를 설정해야 합니다:

jshell --enable-preview

javac --release 14 --enable-preview Author.java

다음 몇 섹션에서 언어 및 JVM 기능에 대해 설명하겠습니다.

추천 독서: 리눅스에 Java 14 설치하기

1. 스위치 표현식

프리뷰 기능으로 남아 있던 스위치 표현식은 마침내 지난 두 릴리스, Java 12와 Java 13에서 영구적인 상태를 얻었습니다.

  • Java 12에서는 패턴 매칭을 위한 람다 구문을 도입하여 다중 case 레이블을 허용하고 장황한 코드를 방지했습니다. 또한, 모든 입력 case가 처리되지 않으면 컴파일 오류가 발생하도록 강제하는 완전한 case를 시행했습니다.
  • Java 13은 두 번째 프리뷰에서 표현식에서 값 반환을 위해 break 대신 yield 문을 도입했습니다.

Java 14에서는 이제 이러한 기능을 표준으로 채택했습니다.

String result = switch (day) {
            case "M", "W", "F" -> "MWF";
            case "T", "TH", "S" -> "TTS";
            default -> {
                if(day.isEmpty())
                    yield "Please insert a valid day.";
                else
                    yield "Looks like a Sunday.";
            }

        };
System.out.println(result);
Java 14 Switch Expressions

참고: Yield는 Java의 새로운 키워드가 아닙니다. 스위치 표현식에서만 사용됩니다.

2. instanceof에 대한 패턴 매칭 (프리뷰)

어떤 Java 개발자에게든 코드베이스를 보여달라고 요청하면 코드 전체에 instanceof 조건을 잘 활용한 것을 볼 수 있습니다. 구체적으로, instanceof 조건 확인은 일반적으로 타입 캐스팅이 이어집니다.

Java 14는 이 장황함을 제거하여 조건부 추출을 훨씬 간결하게 만들었습니다.

Java 14 이전:

if (obj instanceof Journaldev) {
  Journaldev jd = (Journaldev) obj;
  System.out.println(jd.getAuthor());
}

Java 14부터:

if (obj instanceof Journaldev jd) {
  System.out.println(jd.getAuthor());
}

위의 코드에서 jd 인스턴스는 objJournaldev 유형인 경우에만 할당됩니다. 변수의 범위는 조건 블록에만 제한됩니다.

3. 도움이되는 NullPointerExceptions

Null Pointer Exceptions은 개발자에게 악몽입니다. 이전에는 Java 13까지 NPE를 디버깅하는 것이 까다로웠습니다. 스택 트레이스에서는 라인 번호만 표시되기 때문에 다른 디버깅 도구로 빠져나가거나 변수/메서드를 수동으로 찾아야 했습니다.

Java 14 이전:

String name = jd.getBlog().getAuthor()

//스택 트레이스
Exception in thread "main" java.lang.NullPointerException
    at NullPointerExample.main(NullPointerExample.java:5)

Java 14에서는 더 구체적인 스택을 제공하는 새로운 JVM 기능을 소개했습니다:

Exception in thread "main" java.lang.NullPointerException: Cannot invoke "Blog.getAuthor()" because the return value of "Journaldev.getBlog()" is null
    at NullPointerExample.main(NullPointerExample.java:4)

참고: 위의 기능은 언어 기능이 아닙니다. 이것은 런타임 환경의 향상입니다.

4. 레코드 (미리보기)

A record is a data class that stores pure data. The idea behind introducing records is to quickly create simple and concise classes devoid of boilerplate code.

일반적으로 Java의 클래스는 equals(), hashCode(), getter 및 setter 메서드를 구현해야 합니다. 일부 IDE는 이러한 클래스의 자동 생성을 지원하지만 코드는 여전히 장황합니다. record를 사용하면 다음과 같이 클래스를 정의하기만 하면 됩니다.

record Author(){}
//or
record Author (String name, String topic) {}

Java 컴파일러는 생성자, private final 필드, 접근자, equals/hashCodetoString 메서드를 자동으로 생성합니다. 위 클래스의 자동 생성된 getter 메서드는 name()topic()입니다.

생성된 코드를 살펴보려면 javac를 사용하여 프로그램을 컴파일한 후에 javap Author를 사용하십시오. 다음 설명은 다음과 같은 record Author (String name, String topic) {}를 위한 생성된 클래스를 보여줍니다:

Javap Records Java 14

레코드의 의미는 Kotlin의 데이터 클래스와 유사합니다

또한, 다음과 같은 방식으로 레코드에 추가적인 필드, 메서드 및 생성자를 추가할 수 있습니다:

record Author (int id, String name, String topic) {
    static int followers;

    public static String followerCount() {
        return "Followers are "+ followers;
    }

    public String description(){
        return "Author "+ name + " writes on "+ topic;
    }

    public Author{
    if (id < 0) {
        throw new IllegalArgumentException( "id must be greater than 0.");
     }
   }
}

레코드 내에서 정의된 추가 생성자는 Compact 생성자라고합니다. 이는 어떤 매개변수도 포함하지 않으며 단순히 규범적인 생성자의 확장입니다.

A compact constructor wouldn’t be generated as a separate constructor by the compiler. Instead, it is used for validation cases and would be invoked at the start of the main constructor.

레코드에 관한 몇 가지 중요한 사항:

  • A record can neither extend a class nor it can be extended by another class. It’s a final class.
  • 레코드는 추상 일 수 없습니다
  • 레코드는 다른 클래스를 확장할 수 없으며 몸체 내에서 인스턴스 필드를 정의할 수 없습니다. 인스턴스 필드는 상태 설명에서만 정의해야 합니다
  • 선언된 필드는 private 및 final입니다
  • 레코드의 몸체는 정적 필드와 메서드를 허용합니다

추천 독서: Java Records

4.1) 레코드의 참조 필드 안의 값은 변경될 수 있습니다.

객체로 정의된 필드의 경우, 참조만 불변입니다. 하지만 내부 값은 수정할 수 있습니다. 다음 예시는 ArrayList가 수정된 레코드를 보여줍니다. ArrayList가 변경될 때마다 값이 수정되는 것을 확인할 수 있습니다.

Java 14 Records Mutable Values For References

4.2) 레코드는 인터페이스를 구현할 수 있습니다.

다음 코드는 레코드로 인터페이스를 구현하는 예시를 보여줍니다:

record Author(String name, String topic) implements Information {
  public String getFullName() {
    return "Author "+ name + " writes on " + topic;
  }
}

interface Information {
  String getFullName();
}

위 코드의 실행 결과는 JShell에서 다음과 같습니다:

Java 14 Records With Interface

4.3) 레코드는 여러 개의 생성자를 지원합니다.

레코드는 아래와 같이 매개변수와 함께 또는 없이 여러 개의 생성자를 선언할 수 있습니다:

record Author(String name, String topic) {
  public Author() {

    this("NA", "NA");
  }

  public Author(String name) {

    this(name, "NA");
  }
}

4.4) 레코드는 액세서 메소드 수정을 허용합니다.

상태 설명에 정의된 필드에 대한 공개 액세서 메소드를 생성하지만, 레코드는 아래에 표시된대로 본문에서 액세서 메소드를 재정의할 수 있도록 합니다.

record Author(String name, String topic) {
  public String name() {
        return "This article was written by " + this.name;
    }
}

4.5) 런타임에서 레코드 및 그 구성 요소 확인

레코드는 클래스가 레코드인지 확인하고 그 필드와 유형을 살펴보기 위해 isRecord()getRecordComponents()를 제공합니다. 다음 그림은 이것이 어떻게 수행되는지를 보여줍니다.

Java 14 Records Runtime Check

위의 코드 예제에서 레코드에 추가 필드와 메소드를 추가했지만, 이를 과도하게 하지 않도록 주의하십시오. 레코드는 순수한 데이터 운송자로 설계되었으며 많은 추가 메소드를 구현하려는 경우 일반 클래스로 되돌아가는 것이 좋습니다.

5. 텍스트 블록 (미리보기)

텍스트 블록은 Java 13에서 미리보기 기능으로 소개되었으며 다중 줄 문자열을 쉽게 생성할 수 있도록 설계되었습니다. HTML 및 JSON 또는 SQL 쿼리 문자열을 쉽게 생성하는 데 유용합니다.

Java 14에서도 텍스트 블록은 여전히 미리보기 상태이며 몇 가지 새로운 추가 기능이 있습니다. 이제 다음을 사용할 수 있습니다:

  • 백슬래시를 사용하여 멋지게 다중 줄 문자열 블록을 표시합니다.
  • \s는 컴파일러에 의해 기본적으로 무시되는 후행 공백을 고려하는 데 사용됩니다. 그것 앞에 있는 모든 공백을 보존합니다.
String text = """
                Did you know \
                Java 14 \
                has the most features among\
                all non-LTS versions so far\
                """;

String text2 = """
                line1
                line2 \s
                line3
                """;


String text3 = "line1\nline2 \nline3\n"

//text2와 text3는 동일합니다.

참고: OpenJDK 14

Source:
https://www.digitalocean.com/community/tutorials/java-14-features