웹사이트 검색

자바 10 기능


Java 10은 23년 역사상 가장 빠른 Java 버전 릴리스입니다. Java는 느린 성장과 진화로 인해 비판을 받았지만 Java 10은 이러한 개념을 깨뜨렸습니다. Java 10은 미래 지향적인 변경 사항이 많이 포함된 릴리스이며 그 범위와 영향은 명확하지 않을 수 있지만 엄청난 영향을 미칩니다. 이 기사에서는 Java10 릴리스에 추가된 다양한 기능에 대해 설명합니다. 그 전에 Java 릴리스 모델에 도입된 몇 가지 변경 사항을 살펴보겠습니다.

장기 지원 모델

2017년부터 Oracle과 Java 커뮤니티는 Java에 대한 새로운 6개월 주기로의 전환을 발표했습니다. Oracle Java SE 제품에 대한 LTS(장기 지원) 모델로 이동했습니다. 이것은 무엇을 의미 하는가? 제품의 LTS 버전은 Oracle의 프리미어 및 지속적인 지원을 제공할 것이며 3년마다 목표로 삼을 것입니다. 각 Java 릴리스는 하나 또는 두 개의 주요 기능을 모델로 하며 이러한 기능이 릴리스를 구동합니다. 장애물이 있으면 출시가 연기되고 출시가 늦어집니다. Project Jigsaw는 Java 9의 주요 기능으로 릴리스 날짜를 몇 번 미루었고 릴리스가 1.5년 이상 지연되었습니다. 6개월 케이던스 릴리스는 릴리스 트레인을 따릅니다. 출시 열차는 6개월마다 일정이 있습니다. 컷을 열차에 탑승하게 만드는 기능; 그렇지 않으면 다음 예정된 기차를 기다립니다.

오라클 JDK와 오픈 JDK 비교

보다 개발자에게 친숙하기 위해 Oracle 및 Java 커뮤니티는 이제 OpenJDK 바이너리를 기본 JDK로 승격합니다. 이는 재배포에 대한 다양한 제한이 있었던 Oracle이 JDK 바이너리를 독점하고 라이선스를 부여했던 초기에 비해 큰 안도감을 줍니다. 그러나 Oracle은 JDK를 계속 생산하지만 장기 지원 릴리스에 한합니다. 이는 개방형 JDK 바이너리를 컨테이너의 일부로 배포할 수 있으므로 클라우드 및 컨테이너 친화적인 방향으로 나아가는 것입니다. 이것은 무엇을 의미 하는가? Open JDK 바이너리는 6개월마다 릴리스되고 Oracle JDK 바이너리는 3년마다 릴리스됩니다(LTS 버전). 어떤 JDK 바이너리가 채택됩니까? 대규모 조직에서는 버전 간에 이동하는 데 시간이 걸립니다. 그들은 할 수 있을 때까지 버전에 집착합니다. Java 6에 대한 업계 채택은 Java 7보다 많았으며 업계는 점진적으로 Java 9 및 10(비 LTS 릴리스)으로 이동하고 있습니다. 2018년 9월 예정인 Java 11은 LTS 릴리스입니다.

자바 10 기능

Java 10에서 사용할 수 있는 기능을 살짝 살펴보겠습니다.

시간 기반 릴리스 버전 관리(JEP 322)

시간 기반 릴리스 주기를 채택하면서 Oracle은 현재 및 미래의 시간 기반 릴리스 모델을 위해 Java SE 플랫폼 및 JDK의 버전 문자열 체계와 관련 버전 관리 정보를 변경했습니다. 버전 번호의 새 패턴은 다음과 같습니다. $FEATURE.$INTERIM.$UPDATE.$PATCH $FEATURE: 카운터는 6개월마다 증가하며 기능 릴리스 버전을 기반으로 합니다(예: JDK 10). , JDK 11. $INTERIM: 호환 가능한 버그 수정 및 개선 사항이 포함되어 있지만 호환되지 않는 변경 사항은 없는 비기능 릴리스에 대해 카운터가 증가합니다. 일반적으로 6개월 동안 임시 릴리스가 없으므로 이 값은 0입니다. 이것은 릴리스 모델에 대한 향후 개정판을 위해 유지되었습니다. $UPDATE: 최신 기능의 보안 문제, 회귀 및 버그를 수정하는 호환 업데이트 릴리스에 대해 카운터가 증가합니다. 이 기능은 기능 릴리스 후 1개월, 이후 3개월마다 업데이트됩니다. 2018년 4월 릴리스는 JDK 10.0.1, 7월 릴리스는 JDK 10.0.2 등 $PATCH: 중요한 문제를 수정하기 위한 긴급 릴리스에 대해 카운터가 증가합니다. 이러한 카운터 값을 프로그래밍 방식으로 가져오기 위해 새 API가 추가되었습니다. 한 번 보자;

Version version = Runtime.version();
version.feature();
version.interim();
version.update();
version.patch();

이제 버전 정보를 반환하는 Java 실행기를 살펴보겠습니다.

$ java -version
java version "10" 2018-03-20
Java(TM) SE Runtime Environment 18.3 (build 10+46)
Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10+46, mixed mode)

0 이외의 다른 카운터가 없기 때문에 버전 번호 형식은 "10\입니다. 릴리스 날짜가 추가됩니다. 18.3은 2018년 및 3번째 달로 읽을 수 있으며 빌드 10+46은 버전 10의 46번째 빌드입니다. JDK 10.0.1의 가상 빌드 93의 경우 빌드는 10.0.1+939입니다. ### Local-Variable Type Inference(JEP 286)

Local-Variable Type Inference는 개발자를 위한 Java 10의 가장 큰 새 기능입니다. 이니셜라이저를 사용하여 지역 변수 선언에 형식 유추를 추가합니다. 로컬 형식 유추는 다음 시나리오에서만 사용할 수 있습니다.

  • 이니셜라이저가 있는 로컬 변수에만 제한됨
  • 향상된 for 루프 또는 인덱스의 인덱스
  • for 루프에서 선언된 로컬

사용법을 살펴보겠습니다.

var numbers = List.of(1, 2, 3, 4, 5); // inferred value ArrayList<String>
// Index of Enhanced For Loop
for (var number : numbers) {
	System.out.println(number);
}
// Local variable declared in a loop
for (var i = 0; i < numbers.size(); i++) {
	System.out.println(numbers.get(i));
}

이에 대한 자세한 내용은 Java 10 지역 변수 유형 inference.13에 대한 독점 게시물에서 읽을 수 있습니다. ### 실험적 Java 기반 JIT 컴파일러(JEP 317)

이 기능을 사용하면 Java 기반 JIT 컴파일러인 Graal을 Linux/x64 플랫폼에서 실험적 JIT 컴파일러로 사용할 수 있습니다. 이것은 Java 10 기능 목록에서 가장 미래 지향적인 포함입니다. Graal은 Java 9에서 도입되었습니다. 우리에게 익숙한 JIT 컴파일러의 대안입니다. 이것은 JVM에 대한 플러그인입니다. 즉, JIT 컴파일러가 JVM에 연결되어 있지 않고 JVMCI와 호환되는 다른 플러그인(Java-Level JVM 컴파일러 인터페이스)으로 동적으로 연결 및 대체될 수 있습니다. 또한 Java 세계에서 AOT(Ahead of Time) 컴파일을 제공합니다. 다국어 언어 해석도 지원합니다. "Java 바이트 코드를 기계 코드로 변환하기 위해 Java로 작성된 Java 기반 JIT 컴파일러입니다.” 헷갈리시죠?JVM이 Java로 작성되었다면 JVM을 실행하기 위해 JVM이 필요하지 않나요?JVM은 AOT로 컴파일이 가능하고 JIT 컴파일러는 JVM 내에서 사용할 수 있어 라이브 코드 최적화를 통해 성능을 향상시킬 수 있습니다.Graal은 처음부터 Java로 JIT 컴파일러를 완전히 재작성했습니다. 이전 JIT 컴파일러는 C++로 작성되었습니다. 모든 프로그래밍 언어의 최종 진화 단계로 간주됩니다. 다음 jvm 매개변수를 사용하여 Graal로 전환할 수 있습니다.

-XX:+UnlockExperimentalVMOptions -XX:+UseJVMCICompiler

Chris Seaton 프레젠테이션에서 Graal에 대해 자세히 알아볼 수 있습니다.16. ### 애플리케이션 클래스-데이터 공유(JEP 310)

이 기능은 시작 공간을 개선하는 데 도움이 되며, 기존 클래스 데이터 공유("CDS”) 기능을 확장하여 애플리케이션 클래스를 공유 아카이브에 배치할 수 있습니다. JVM은 시작하는 동안 몇 가지 예비 단계를 수행하며, 그 중 하나는 클래스를 로드하는 것입니다. 여러 개의 클래스가 있는 jar가 여러 개 있는 경우 첫 번째 요청의 지연이 명확하게 표시됩니다. 이는 부팅 시간이 중요한 서버리스 아키텍처에서 문제가 됩니다. 응용 프로그램 시작 시간을 줄이기 위해 응용 프로그램 클래스 데이터 공유를 사용할 수 있습니다. 아이디어는 서로 다른 Java 프로세스 간에 공통 클래스 메타데이터를 공유하여 공간을 줄이는 것입니다. 이는 다음 3단계로 달성할 수 있습니다. 보관할 클래스 결정: Java 실행기를 사용하여 보관할 파일 목록을 만듭니다. 이는 다음 매개변수로 달성할 수 있습니다.

$java -Xshare:off -XX:+UseAppCDS -XX:DumpLoadedClassList=hello.lst -cp hello.jar HelloWorld

AppCDS 아카이브 생성: Java 실행기를 사용하여 Application CDS에 사용할 파일 목록의 아카이브를 생성합니다. 이는 다음 매개변수를 통해 수행할 수 있습니다.

$java -Xshare:dump -XX:+UseAppCDS -XX:SharedClassListFile=hello.lst -XX:SharedArchiveFile=hello.jsa -cp hello.jar

AppCDS 아카이브 사용: Application CDS를 사용하려면 다음 매개변수와 함께 Java 시작 프로그램을 사용하십시오.

$java -Xshare:on -XX:+UseAppCDS -XX:SharedArchiveFile=hello.jsa -cp hello.jar HelloWorld

G1용 병렬 전체 GC(JEP 307)

G1 가비지 수집기는 JDK 9에서 기본 설정되었습니다. G1 가비지 수집기는 전체 가비지 수집을 방지하지만, 수집을 위한 동시 스레드가 메모리를 충분히 빠르게 재생하지 못하는 경우 사용자 경험에 영향을 미칩니다. 이 변경은 전체 GC를 병렬로 만들어 G1 최악의 대기 시간을 개선합니다. G1 수집기의 mark-sweep-compact 알고리즘은 이 변경의 일부로 병렬화되며 수집을 위한 동시 스레드가 충분히 빠르게 메모리를 재생하지 못할 때 트리거됩니다.25. ### 가비지 수집기 인터페이스(JEP 304)

이 JEP는 미래형 변화입니다. 공통 가비지 수집기 인터페이스를 도입하여 다양한 가비지 수집기의 코드 격리를 개선합니다. 이 변경은 내부 GC 코드에 더 나은 모듈성을 제공합니다. 향후 기존 코드베이스를 변경하지 않고 새 GC를 추가하는 데 도움이 될 것이며 이전 GC.26을 제거하거나 관리하는 데에도 도움이 될 것입니다. ### 추가 유니코드 언어 태그 확장(JEP 314)

이 기능은 java.util.Locale 및 관련 API를 향상시켜 BCP 47 언어 태그의 추가 유니코드 확장을 구현합니다. Java SE 9부터 지원되는 BCP 47 U 언어 태그 확장은 "ca\ 및 "nu\입니다. 이 JEP는 다음 추가 확장에 대한 지원을 추가합니다.

  • cu(통화 유형)
  • fw(주의 첫째 날)
  • rg(지역 재정의)
  • tz(시간대)

이러한 추가 확장을 지원하기 위해 U 또는 추가 확장을 기반으로 정보를 제공하도록 다양한 API를 변경합니다.

java.text.DateFormat::get*Instance
java.text.DateFormatSymbols::getInstance
java.text.DecimalFormatSymbols::getInstance
java.text.NumberFormat::get*Instance
java.time.format.DateTimeFormatter::localizedBy
java.time.format.DateTimeFormatterBuilder::getLocalizedDateTimePattern
java.time.format.DecimalStyle::of
java.time.temporal.WeekFields::of
java.util.Calendar::{getFirstDayOfWeek,getMinimalDaysInWeek}
java.util.Currency::getInstance
java.util.Locale::getDisplayName
java.util.spi.LocaleNameProvider

루트 인증서(JEP 319)

OpenJDK를 홍보하고 커뮤니티 사용자에게 더 매력적으로 만들기 위해 이 기능은 JDK에서 기본 루트 인증 기관(CA) 인증서 집합을 제공합니다. 이는 또한 Oracle 및 Open JDK 바이너리가 모두 기능적으로 동일함을 의미합니다. TLS와 같은 중요한 보안 구성 요소는 향후 OpenJDK 빌드에서 기본적으로 작동합니다.30. ### 스레드 로컬 핸드셰이크(JEP 312)

이는 성능 향상을 위한 내부 JVM 기능입니다. 핸드셰이크 작업은 해당 스레드가 safepoint 상태에 있는 동안 각 JavaThread에 대해 실행되는 콜백입니다. 콜백은 스레드를 차단된 상태로 유지하면서 스레드 자체 또는 VM 스레드에 의해 실행됩니다. 이 기능은 전역 VM safepoint를 수행하지 않고 스레드에서 콜백을 실행하는 방법을 제공합니다. 모든 스레드가 아닌 개별 스레드를 중지하는 것이 가능하고 저렴하게 만드십시오.31. ### 대체 메모리 장치의 힙 할당(JEP 316)

애플리케이션은 메모리를 많이 사용하게 되었고 클라우드 네이티브 애플리케이션, 메모리 내 데이터베이스, 스트리밍 애플리케이션이 증가했습니다. 이러한 서비스를 제공하기 위해 다양한 메모리 아키텍처를 사용할 수 있습니다. 이 기능은 HotSpot VM의 기능을 향상시켜 사용자가 지정한 NV-DIMM과 같은 대체 메모리 장치에 Java 개체 힙을 할당합니다. 이 JEP는 원자 연산의 의미 체계를 포함하여 DRAM과 동일한 의미 체계를 갖는 대체 메모리 장치를 대상으로 하며, 따라서 기존 애플리케이션 코드를 변경하지 않고도 개체 힙에 DRAM 대신 사용할 수 있습니다.32. ### 네이티브 헤더 생성 도구 – javah 제거(JEP 313)

이것은 JDK에서 javah 도구를 제거하기 위한 하우스키핑 변경입니다. 도구 기능은 JDK 8의 일부로 javac에 추가되어 컴파일 시 javah를 쓸모없게 렌더링할 때 기본 헤더 파일을 작성할 수 있는 기능을 제공합니다.35. ### JDK 포리스트를 단일 리포지토리로 통합(JEP 296)

수년 동안 JDK 코드베이스를 위한 다양한 Mercurial 리포지토리가 있었습니다. 다른 리포지토리는 약간의 이점을 제공하지만 다양한 운영상의 단점도 있습니다. 이러한 변화의 일환으로 JDK 포리스트의 수많은 리포지토리가 단일 리포지토리로 결합되어 개발을 단순화하고 능률화합니다.36. ### API 변경

Java 10은 API를 추가 및 제거했습니다(예, 오타가 아닙니다). Java 9에서는 향후 릴리스에서 특정 API가 제거되도록 표시된 개선된 사용 중단을 도입했습니다. API 제거됨: 여기에서 API가 제거된 것을 확인할 수 있습니다. 몇 가지 추가 사항을 살펴보겠습니다.

  • List, Map & Set 인터페이스는 정적 copyOf(Collection) 메소드와 함께 추가됩니다. 제공된 항목을 포함하는 수정 불가능한 목록, 맵 또는 집합을 반환합니다. 목록의 경우 지정된 목록이 이후에 수정되면 반환된 목록은 그러한 수정 사항을 반영하지 않습니다.
  • 선택 사항 및 기본 변형은 메서드 또는 ElseThrow()를 가져옵니다. 이것은 get()과 정확히 동일하지만 java 문서에는 get()보다 선호되는 대안이라고 명시되어 있습니다.
  • Collectors 클래스는 수정 불가능한 컬렉션(Set, List, Map)을 수집하기 위한 다양한 방법을 얻습니다.

List<String> actors = new ArrayList<>();
actors.add("Jack Nicholson");
actors.add("Marlon Brando");
System.out.println(actors); // prints [Jack Nicholson, Marlon Brando]
// New API added - Creates an UnModifiable List from a List.
List<String> copyOfActors = List.copyOf(actors);
System.out.println(copyOfActors); // prints [Jack Nicholson, Marlon Brando]
// copyOfActors.add("Robert De Niro"); Will generate an
// UnsupportedOperationException
actors.add("Robert De Niro");
System.out.println(actors);// prints [Jack Nicholson, Marlon Brando, Robert De Niro]
System.out.println(copyOfActors); // prints [Jack Nicholson, Marlon Brando]
		
String str = "";
Optional<String> name = Optional.ofNullable(str);
// New API added - is preferred option then get() method
name.orElseThrow(); // same as name.get()  

// New API added - Collectors.toUnmodifiableList
List<String> collect = actors.stream().collect(Collectors.toUnmodifiableList());
// collect.add("Tom Hanks"); // Will generate an
// UnsupportedOperationException

결론

이 기사에서는 Java 10의 다양한 새 기능 추가에 대해 살펴보았습니다. 여기에서 중요한 사항이 누락되었다고 생각되면 의견을 통해 알려주십시오. 평소와 같이 여기 GitHub에서 전체 코드를 확인할 수 있습니다.