웹사이트 검색

자바 12 기능


마지막으로 6개월 릴리스 주기의 일부인 JDK 12가 출시되었습니다. 마지막 Java LTS 버전 11 이후에 제공됩니다. 이전에 Java 11 기능에 대해 자세히 논의했습니다. 오늘 우리는 Java 12 기능에 대해 논의하고 개발자를 위해 무엇을 제공하는지 확인할 것입니다. Java 12는 2019년 3월 19일에 출시되었습니다. 비 LTS 버전입니다. 따라서 장기적으로 지원되지 않습니다.

자바 12 기능

중요한 Java 12 기능 중 일부는 다음과 같습니다.

  1. JVM 변경 사항 - JEP 189, JEP 346, JEP 344 및 JEP 230.
  2. 표현식 전환
  3. 파일 불일치() 방법
  4. 소형 숫자 형식
  5. Stream API의 티잉 수집기
  6. 자바 문자열의 새 메서드 - indent(), transform(), describeConstable() 및 resolveConstantDesc().
  7. JEP 334: JVM 상수 API
  8. JEP 305: instanceof에 대한 패턴 일치
  9. 원시 문자열 리터럴이 JDK 12에서 제거되었습니다.

이러한 모든 Java 12 기능을 하나씩 살펴보겠습니다.

JVM 변경 사항

1. JEP 189 - Shenandoah: A Low-Pause-Time Garbage Collector(실험적)

RedHat은 GC 일시 중지 시간을 줄이기 위해 Shenandoah Garbage Collector를 시작했습니다. 아이디어는 실행 중인 Java 스레드와 동시에 GC를 실행하는 것입니다. 힙 크기와 관계없이 일관되고 예측 가능한 짧은 일시 중지를 목표로 합니다. 따라서 힙 크기가 15MB인지 15GB인지는 중요하지 않습니다. Java 12의 실험적 기능입니다.

2. JEP 346 - G1에서 사용하지 않은 커밋된 메모리를 즉시 반환

Java 12에 따르면 G1은 이제 애플리케이션이 비활성화된 동안 Java 힙 메모리를 확인하고 이를 운영 체제로 반환합니다. 이는 여유 메모리를 보존하고 사용하기 위한 선제적 조치입니다.

3. JEP 344 : G1용 중단 가능한 혼합 컬렉션

G1 효율성 개선에는 정의된 일시 중지 대상을 초과할 수 있는 경우 G1 혼합 컬렉션을 중단할 수 있도록 하는 것이 포함됩니다. 이는 혼합 컬렉션 집합을 필수 및 선택으로 분할하여 수행됩니다. 따라서 G1 수집기는 일시 중지 시간 목표를 충족하기 위해 먼저 필수 집합을 수집하는 데 우선 순위를 지정할 수 있습니다.

4. JEP 230 및 344

Microbenchmark 제품군, JEP 230 기능은 JDK 소스 코드에 기본 마이크로벤치마크 제품군을 추가합니다. 이를 통해 개발자는 쉽게 기존 마이크로벤치마크를 실행하고 새로운 마이크로벤치마크를 생성할 수 있습니다. 둘이 아닌 하나의 AArch64 포트인 JEP 344는 32비트 ARM 포트와 64비트 aarch64 포트를 유지하면서 arm64 포트와 관련된 모든 소스를 제거합니다. 이를 통해 기여자는 단일 64비트 ARM 구현에 노력을 집중할 수 있습니다.

5. JEP 341 기본 CDS 아카이브

이렇게 하면 64비트 플랫폼에서 기본 클래스 목록을 사용하여 CDS(클래스 데이터 공유) 아카이브를 생성하도록 JDK 빌드 프로세스가 향상됩니다. 시작 시간을 개선하는 것이 목표입니다. Java 12부터 CDS는 기본적으로 ON입니다. CDS를 끈 상태에서 프로그램을 실행하려면 다음을 수행하십시오.

java -Xshare:off HelloWorld.java

이제 이것은 프로그램의 시작 시간을 지연시킬 것입니다.

언어 변경 및 기능

Java 12에는 많은 언어 기능이 도입되었습니다. 몇 가지 구현을 살펴보겠습니다.

1. 스위치 표현식(미리보기)

Java 12에는 패턴 일치를 위한 향상된 Switch 표현식이 있습니다. 미리 보기 언어 기능으로 JEP 325에 도입된 새 구문은 L ->입니다. 다음은 Switch 식에 대해 유의해야 할 사항입니다.

  • 새 구문은 오류를 방지하기 위해 break 문이 필요하지 않습니다.
  • 스위치 표현식이 더 이상 빠지지 않습니다.
  • 또한 동일한 레이블에 여러 상수를 정의할 수 있습니다.
  • default 대소문자는 이제 Switch Expressions에서 필수입니다.
  • break는 사례 자체에서 값을 반환하기 위해 Switch Expressions에서 사용됩니다.

클래식 스위치 문:

String result = "";
        switch (day) {
            case "M":
            case "W":
            case "F": {
                result = "MWF";
                break;
            }
            case "T":
            case "TH":
            case "S": {
                result = "TTS";
                break;
            }
        };

        System.out.println("Old Switch Result:");
        System.out.println(result);

새로운 Switch 표현식을 사용하면 어디에서나 중단을 설정할 필요가 없으므로 논리 오류를 방지할 수 있습니다!

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

        };

        System.out.println(result);

JDK 12를 사용하여 새로운 Switch Expression이 포함된 아래 프로그램을 실행해 봅시다.

public class SwitchExpressions {

    public static void main(String[] args)
    {
        System.out.println("New Switch Expression result:");
        executeNewSwitchExpression("M");
        executeNewSwitchExpression("TH");
        executeNewSwitchExpression("");
        executeNewSwitchExpression("SUN");
    }

    public static void executeNewSwitchExpression(String day){

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

        };

        System.out.println(result);
    }
}

이것은 미리보기 기능이므로 언어 수준을 Java 12 미리보기로 선택했는지 확인하십시오. 위의 코드를 컴파일하려면 다음 명령을 실행하십시오.

javac -Xlint:preview --enable-preview -source 12 src/main/java/SwitchExpressions.java

컴파일된 프로그램을 실행한 후 콘솔에서 다음을 얻습니다.

스위치 식은 미리 보기 언어 기능입니다. 이는 완성되더라도 향후 Java 릴리스에서 확인되지 않을 수 있음을 의미합니다.

2. File.mismatch 방법

Java 12에는 두 파일을 비교하기 위해 다음 메서드가 추가되었습니다.

public static long mismatch(Path path, Path path2) throws IOException

이 메서드는 첫 번째 불일치 위치를 반환하거나 불일치가 없으면 -1L을 반환합니다. 다음 시나리오에서는 두 파일이 일치하지 않을 수 있습니다.

  • 바이트가 동일하지 않은 경우. 이 경우 일치하지 않는 첫 번째 바이트의 위치가 반환됩니다.
  • 파일 크기가 동일하지 않습니다. 이 경우 더 작은 파일의 크기가 반환됩니다.

IntelliJ Idea의 예제 코드 스니펫은 다음과 같습니다.

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;

public class FileMismatchExample {

    public static void main(String[] args) throws IOException {
        Path filePath1 = Files.createTempFile("file1", ".txt");
        Path filePath2 = Files.createTempFile("file2", ".txt");
        Files.writeString(filePath1,"JournalDev Test String");
        Files.writeString(filePath2,"JournalDev Test String");

        long mismatch = Files.mismatch(filePath1, filePath2);

        System.out.println("File Mismatch position... It returns -1 if there is no mismatch");

        System.out.println("Mismatch position in file1 and file2 is >>>>");
        System.out.println(mismatch);

        filePath1.toFile().deleteOnExit();
        filePath2.toFile().deleteOnExit();

        System.out.println();

        Path filePath3 = Files.createTempFile("file3", ".txt");
        Path filePath4 = Files.createTempFile("file4", ".txt");
        Files.writeString(filePath3,"JournalDev Test String");
        Files.writeString(filePath4,"JournalDev.com Test String");

        long mismatch2 = Files.mismatch(filePath3, filePath4);

        System.out.println("Mismatch position in file3 and file4 is >>>>");
        System.out.println(mismatch2);

        filePath3.toFile().deleteOnExit();
        filePath4.toFile().deleteOnExit();



    }

}

위의 Java 프로그램이 컴파일되고 실행될 때의 출력은 다음과 같습니다.

3. 간결한 숫자 형식

import java.text.NumberFormat;
import java.util.Locale;

public class CompactNumberFormatting {


    public static void main(String[] args)
    {
        System.out.println("Compact Formatting is:");
        NumberFormat upvotes = NumberFormat
                .getCompactNumberInstance(new Locale("en", "US"), NumberFormat.Style.SHORT);
        upvotes.setMaximumFractionDigits(1);

        System.out.println(upvotes.format(2592) + " upvotes");


        NumberFormat upvotes2 = NumberFormat
                .getCompactNumberInstance(new Locale("en", "US"), NumberFormat.Style.LONG);
        upvotes2.setMaximumFractionDigits(2);
        System.out.println(upvotes2.format(2011) + " upvotes");
    }


}

4. 티잉 컬렉터

Teeing Collector는 Streams API에 도입된 새로운 수집기 유틸리티입니다. 이 컬렉터에는 3개의 인수(2개의 컬렉터와 Bi-function)가 있습니다. 모든 입력 값은 각 수집기로 전달되고 결과는 Bi-function에서 사용할 수 있습니다.

double mean = Stream.of(1, 2, 3, 4, 5)
                .collect(Collectors.teeing(
                        summingDouble(i -> i),
                        counting(),
                        (sum, n) -> sum / n));

System.out.println(mean);

출력은 3.0입니다.

5. 자바 스트링의 새로운 메소드

Java 12에는 다음과 같은 4가지 새로운 메서드가 도입되었습니다.

  • 들여쓰기(int n)
  • 변환(함수 f)
  • 선택 사항 describeConstable()
  • String resolveConstantDesc (MethodHandles.Lookup 조회)

위의 메서드와 구현에 대해 자세히 알아보려면 Java 12 문자열 메서드 자습서를 참조하세요.

6. JEP 334: JVM 상수 API

새 패키지 java.lang.constant가 이 JEP와 함께 도입되었습니다. 상수 풀을 사용하지 않는 개발자에게는 그다지 유용하지 않습니다.

7. JEP 305: instanceof에 대한 패턴 일치(미리 보기)

또 다른 미리보기 언어 기능! 유형을 다른 유형으로 유형 변환하는 이전 방법은 다음과 같습니다.

if (obj instanceof String) {
    String s = (String) obj;
    // use s in your code from here
}

새로운 방법은 다음과 같습니다.

if (obj instanceof String s) {
    // can use s directly here
} 

이렇게 하면 불필요했던 일부 유형 캐스팅이 절약됩니다.

원시 문자열 리터럴이 JDK 12에서 제거되었습니다.

이것으로 Java 12 기능에 대한 이 기사를 마칩니다.