The JDK 10 version updates you don't know are here

Recommended reading:

1. Overview of Features

The following are some of the new features introduced in Java 10. For a more detailed introduction to the new features of Java 10, please refer to here .

  • Time-based release version control (JEP 322)
  • Local variable type inference (JEP 286)
  • Experimental JIT compiler (JEP 317)
  • Application data sharing (JEP 310)
  • Parallel Full GC for G1 (JEP 307)
  • Clean up the garbage collector interface (JEP 304)
  • Other Unicode language tag extensions (JEP 314)
  • Root certificate (JEP 319)
  • Thread local handshake (JEP 312)
  • Heap allocation on alternate storage devices (JEP 316)
  • Delete the native head generation tool-javah (JEP 313)
  • Consolidate the JDK forest into a single repository (JEP 296)
  • API changes

2. Time-based release version control (JEP 322)

2.1 The past and present of the release version number

Since Java changed hands, the string naming method of JDK release has been an intriguing topic.

In terms of the short version string format that you see when downloading the JDK,   the number 7u40 before and uafter the version represents the first few revisions since the release of the JDK. However, Oracle has changed the rules to highlight security and the like major  repair (Cirtical patch Updates) version , using  an odd  name, but modified for Bug fixes, API classes, the  maintenance release , the use of  an even number . (There is also a version number  $MAJOR.$MINOR.$SECURITY format to distinguish between bug fixes and API modifications)

For this reason, the existing JDK 6/7 release version has also been renamed. (Demo below)

   Actual                    Hypothetical
Release Type           long               short
------------           ------------------------ 
Security 2013/06       1.7.0_25-b15       7u25
Minor    2013/09       1.7.0_40-b43       7u40
Security 2013/10       1.7.0_45-b18       7u45
Security 2014/01       1.7.0_51-b13       7u51
Minor    2014/05       1.7.0_60-b19       7u60

On the findings, the later re-named from  7u9, 6u37 the beginning, you can count from parity to determine whether to repair major version; as for  7u40 later versions, major patched version  is based on  5 a multiple of, the case of an even number plus one, and  maintenance releases  will be  20 Multiples of. Such a (not intuitive) naming method is standardized in  JEP223  . (Released with JDK 9)

However, since the release of JDK 8, Oracle’s Java architect Mark Reinhold hopes that future Java releases can be based on time and will continue to release new versions with a half-year cycle, so that some useful small features can also be used by developers. , The JEP 223 specification is no longer applicable, and after the release of JDK 9, they once proposed a $YEAR.$MONTH format based on the new version  , but they received great opposition from the community. For this reason, they also proposed three alternatives, collecting each The opinion of the party. ( Https://goo.gl/7CA8B3 )

So, what is the next feature version of Java  8.3? 1803? Still  10? The survey results show that most of the community supports it  10, Stephen Colebourne also issued a request ( https://goo.gl/i5J44T), and said that  Java is not like an operating system such as Ubuntu, which  $YEAR.$MONTH is not appropriate.

In the end, Oracle adopted  $FEATURE.$INTERIM.$UPDATE.$PATCH such a scheme and specified it in  JEP 322  .

2.2 Interpretation of JEP 322 New Model

By adopting a time-based release cycle, Oracle has changed the version string scheme of the Java SE platform and JDK and related version information to apply to current and future time-based release models.

The new pattern of version numbers is:

$FEATURE.$INTERIM.$UPDATE.$PATCH

  • FEATURE $ : Each counter  6 is incremented once a month, and based on the feature release version, for example: JDK 10, JDK 11.
  • $INTERIM : For non-functional versions that contain compatible bug fixes and enhancements but no incompatible changes, the counter will increase. Normally, this will be zero because there will not be any temporary releases for six months. This preserves future revisions to the published model.
  • $UPDATE : The counter will increase for a compatible updated version that solves security issues, regressions, and bugs in newer features. This feature will be updated one month after the feature is released, and every three months thereafter. The April 2018 version is  JDK 10.0.1, the July version is  JDK 10.0.2, and so on
  • $PATCH : The counter will increase for emergency release to solve serious problems.

And added a new API to get these counters programmatically:

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

Now, let's take a look at the Java launcher that returns version information:

$ 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)

The version number format is  10because no other counter is zero. The release date has been added. It can be  18.3 understood as Year 2018 & 3rd Month, and the version  10 + 46 is the version  10 of the  46 version. For  JDK 10.0.1 the hypothetical version  93, the version will be  10.0.1 + 93.

Therefore, for Java 9, the currently available version will be in  9.0.4 this format. As for the feature version released in March 2018,   the new version will be provided by 10the  9month, that is  11, JDK 11 is expected to be a long-term support version. Therefore, on the version string, LTS (long-term support) will also be displayed.

3. Local variable type inference (JEP 286)

3.1 Overview

One of the most obvious enhancements in JDK 10 is the use of initializers for type inference for local variables.

Before Java 9, we had to clearly write out the type of local variable and ensure that it is compatible with the initializer used to initialize it:

String message = "Good bye, Java 9";

In Java 10, this is how we can declare local variables:

@Test
public void whenVarInitWithString_thenGetStringTypeVar() {
    var message = "Hello, Java 10";
    assertTrue(message instanceof String);
}

We did not provide  message the specific type. Instead, we  message marked  varthe type that the compiler would infer from message the type of the initializer on the right  . (In the above example  message is  String type)

Please note that this function is only applicable to local variables with initializers . It cannot be used for member variables, method parameters, return types, etc.-the initializer is necessary, otherwise, the compiler cannot infer its type.

This feature helps us reduce boilerplate code, such as:

Map<Integer, String> map = new HashMap<>();

Can now be rewritten as:

var idToNameMap = new HashMap<Integer, String>();

This also helps us focus on variable names, not variable types.

Another thing to pay attention to is  var not keywords -this ensures var backward compatibility of programs used  as function or variable names. var Is a reserved type name, just like the  int same.

Finally, use  var will not increase runtime overhead, nor will it make Java a dynamically typed language . The variable type is still judged at compile time and cannot be changed later.

3.2 Analysis of illegal use of var

1. If there is no initialization program, it var will not work:

var n; // error: cannot use 'var' on variable without initializer

2. If it is initialized to null, it will not work:

var emptyList = null; // error: variable initializer is 'null'

3. Not applicable to non-local variables:

public var word = "hello"; // error: 'var' is not allowed here

4. Lambda expressions require explicit types, so they cannot be used  var:

var p = (String s) -> s.length() > 10; // error: lambda expression needs an explicit target-type

5. The array initialization program also does not support:

var arr = { 1, 2, 3 }; // error: array initializer needs an explicit target-type

3.3 Guidelines for using var

In some cases, we can use it legally  var, but doing so is not a good idea.

For example, in the case of reduced code readability:

var result = obj.prcoess();

Here, although it can be used legally  var, it is difficult to understand the  process() returned type, which reduces the readability of the code.

java.netThere is an article on (OpenJDK official website) that introduces the  writing guidelines of local variable type inference in Java . This article discusses the posture that should be paid attention to when using this feature and some good suggestions on how to use it.

In addition, var another situation that is best avoided  is in a stream with a longer pipeline:

var x = emp.getProjects.stream()
  .findFirst()
  .map(String::length)
  .orElse(0);

In addition, using it  var with non-reference types may cause unexpected errors.

For example, if we will use it  var with anonymous class instances:

@Test
public void whenVarInitWithAnonymous_thenGetAnonymousType() {
    var obj = new Object() {};
    assertFalse(obj.getClass().equals(Object.class));
}

Now, if we try to assign another Object to it  obj, a compilation error occurs:

obj = new Object(); // error: Object cannot be converted to <anonymous Object>

This is because  obj the inferred type is not Object.

Fourth, the experimental JIT compiler (JEP 317)

Graal  is a dynamic compiler written in Java and integrated with HotSpot JVM. It focuses on high performance and scalability. It is also the basis for the experimental Ahead-of-Time (AOT) compiler introduced in JDK 9.

JDK 10 enables the Graal compiler to be used as an experimental JIT compiler on Linux / x64 platforms.

To use Graal as a JIT compiler, use the following options on the Java command line:

-XX:+UnlockExperimentalVMOptions -XX:+UseJVMCICompiler

Please note that this is an experimental feature and we may not get better performance than existing JIT compilers.

For children's shoes who want to know more, please refer to Chris Seaton's speech: https://chrisseaton.com/truffleruby/jokerconf17/

(Ps: long text + special low-level warning...)

5. Application data sharing (JEP 310)

The class data sharing introduced in JDK 5 allows a group of classes to be preprocessed into a shared archive file, and then memory-mapped at runtime to reduce startup time, which can also be reduced when multiple JVMs share the same archive file Dynamic memory usage.

CDS only allows boot class loaders, restricting this feature to system classes. Application CDS (AppCDS) extends CDS to allow built-in system class loaders. Built-in platform class loader and custom class loader for loading archive classes. This makes it possible to use this feature for application classes.

We can use the following steps to use this feature:

1. Get the list of classes to be archived

The following command  dumps the classes loaded by the HelloWorld application into hello.lst :

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

2. Create AppCDS archive

The following command uses hello.lst  as input to create hello.js A  :

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

3. Use AppCDS to archive

The following command  starts the HelloWorld  application with hello.jsa as input :

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

AppCDS is a commercial feature in Oracle JDK for JDK 8 and JDK 9. It is now open source and can be used publicly.

6. Parallel Full GC for G1 (JEP 307)

The G1 garbage collector is the default garbage collector since JDK 9. However, G1's Full GC uses a single-threaded mark-sweep-compact algorithm.

It has been  changed to the parallel mark-sweep-compact algorithm in  Java 10   , which effectively reduces the dead time during Full GC.

Seven, clean up the garbage collector interface (JEP 304)

This JEP is a future change. By introducing a common garbage collector interface, it improves the code isolation of different garbage collectors.

This change provides better modularity for the internal GC code. In the future, it will help to add new GCs without changing the existing code base, and it will also help to delete or retain previous GCs.

Official motivation explanation:  ( Portal )

Currently, each garbage collector implementation consists src/hotspot/share/gc/$NAME of source files in its  directory, such as G1 in  src/hotspot/share/gc/g1, CMS in  src/hotspot/share/gc/cms etc. However, some scattered information is scattered in HotSpot. For example, most GCs require certain barriers, which need to be implemented in the interpreters C1 and C2 at runtime. These obstacles are not included in the specific directory of the GC, but sharing the interpreter, rather than implementation, C1, and C2, the source code (typically a long guard -if  - ). The same problem applies to diagnostic codes, for example  . This source code layout has several disadvantages:elsechainsMemoryMXBeans

  1. For GC developers, implementing a new garbage collector requires knowledge about all these places and how to extend them to meet their specific needs.

  2. For HotSpot developers who are not GC developers, where to find specific code snippets for a given GC can cause confusion.

  3. It is difficult to exclude a specific garbage collector during construction. This #define INCLUD E_ALL_GCShas long been a way to build a JVM with the only built-in serial collection, but this mechanism has become too rigid.

A cleaner GC interface will make it easier to implement new collectors, make the code cleaner, and it will be easier to exclude one or more collectors at build time. Adding a new garbage collector should implement a set of well-documented interfaces, rather than figuring out all the things that need to be changed in HotSpot.

8. Other Unicode language label extensions (JEP 314)

This feature enhances  java.util.Locale and related APIs to implement other Unicode extensions for BCP 47 language tags. Starting with Java SE 9, the supported BCP 47 U language extensions are "ca" and "nu". The JEP will add support for the following additional extensions:

  • cu (currency type)
  • fw (first day of the week)
  • rg (regional coverage)
  • tz (time zone)

In order to support these additional extensions, the following various APIs have been changed to provide information based on U or additional extensions:

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

Nine, the root certificate (JEP 319)

The cacerts keystore (empty so far) is intended to contain a set of root certificates that can be used to establish trust in the certificate chains used by various security protocols.

As a result, in OpenJDK builds, critical security components such as TLS do not work by default.

With Java 10, Oracle open sourced the root certificate  in the Oracle Java SE Root CA program   to make OpenJDK builds more attractive to developers and reduce the differences between these builds and Oracle JDK builds.

10. Thread local handshake (JEP 312)

This is an internal feature used to improve JVM performance.

The handshake operation is a callback executed for each JavaThread when the thread is in a safe point state. The callback is executed by the thread itself or the VM thread while keeping the thread in a blocked state.

This feature provides a way to execute callbacks on threads without executing global VM safety points. It is possible to stop a single thread, instead of stopping all threads or not stopping threads , and at low cost.

11. Heap allocation on alternate storage devices (JEP 316)

The memory consumption of applications is increasing, and local cloud applications, in-memory databases, and streaming applications are all increasing. To satisfy these services, there are various memory architectures available. This feature enhances the HotSpot VM's ability to allocate Java object heaps on user-specified spare memory devices (such as NV-DIMM).

The goal of this JEP is an optional memory device that has the same semantics as DRAM (including the semantics of atomic operations), so it can be used for object heap instead of DRAM without changing the existing application code .

12. Delete the native head generation tool—javah (JEP 313)

This is a general change to remove javah tools from the JDK  . The tool function is added as part of JDK 8  javac , which provides the javah ability to write useless native header files at compile time  .

Thirteen, merge the JDK forest into a single repository (JEP 296)

Over the years, various Mercurial repositories have been used for the JDK code base. Different repositories do provide some advantages, but they also have various operational disadvantages. As part of this change, many repositories of the JDK forest were merged into one repository to simplify and simplify development.

14. API changes

Java 10 added and removed APIs. Java 9 introduces enhanced deprecations, and some of the APIs are marked for removal in a future version.

So these APIs were deleted: you can   find the deleted APIs here .

New APIs: 73 APIs have been added in Java 10. You can   find and compare the added APIs here .

Let's take a look at the parts that are directly useful to us.

15. Improvements to unmodifiable collections

There are some changes related to unmodifiable collections in Java 10

copyOf()

java.util.List, java.util.Map And  java.util.Set both have a new static method  copyOf(Collection).

It returns an unmodifiable copy of the given Collection:

jshell> var originList = new ArrayList<String>();
originList ==> []

jshell> originList.add("欢迎关注公众号:");
$2 ==> true

jshell> originList.add("我没有三颗心脏");
$3 ==> true

jshell> var copyList = List.copyOf(originList)
copyList ==> [欢迎关注公众号:, 我没有三颗心脏]

jshell> originList.add("获取更多精彩内容")
$5 ==> true

jshell> System.out.println(copyList)
[欢迎关注公众号:, 我没有三颗心脏]

jshell> copyList.add("获取更多精彩内容")
|  异常错误 java.lang.UnsupportedOperationException
|        at ImmutableCollections.uoe (ImmutableCollections.java:73)
|        at ImmutableCollections$AbstractImmutableCollection.add (ImmutableCollections.java:77)
|        at (#7:1)

jshell>

toUnmodifiable()

java.util.Collectors Get other methods to collect Stream into an unmodifiable List, Map, or Set:

@Test(expected = UnsupportedOperationException.class)
public void whenModifyToUnmodifiableList_thenThrowsException() {
    List<Integer> evenList = someIntList.stream()
      .filter(i -> i % 2 == 0)
      .collect(Collectors.toUnmodifiableList());
    evenList.add(4);
}

Any attempt to modify such a collection will result in a  java.lang.UnsupportedOperationException runtime exception.

16. Optinal new method orElseThrow()

java.util.Optional, java.util.OptionalDouble, java.util.OptionalInt And  java.util.OptionalLong there is a new method  orElseThrow(), it does not accept any arguments, if any value does not exist, is thrown  NoSuchElementException:

@Test
public void whenListContainsInteger_OrElseThrowReturnsInteger() {
    Integer firstEven = someIntList.stream()
      .filter(i -> i % 2 == 0)
      .findFirst()
      .orElseThrow();
    is(firstEven).equals(Integer.valueOf(2));
}

It get() is synonymous with the existing  method and is now its preferred alternative.

Guess you like

Origin blog.csdn.net/weixin_45784983/article/details/108276722