What’s New in Java 10?资料
本文为去找网小编(www.7zhao.net)为您推荐的What’s New in Java 10?，希望对您有所帮助，谢谢！
Java 10 Overview
In March 2018, we saw the latest semi-annual release of Java — Java 10.
In this article, we’ll examine the big changes introduced in this version, as well as talk about some of the smaller improvements that will make life easier for developers and ops alike.
Java 10: Big Changes
The two big stories in Java 10 are:
varkeyword, just like you’d imagine with any new language construct, and the new six-month release cycle
Also, developers will be excited to see more API evolution. And, there are runtime improvements, new performance tuning knobs, and the now-perennial improvements that we’ve come to expect with each release.
But there are a number of other interesting things, too, especially if you know how to read in between the lines and look ahead to Java 11 in September.
Local Variable Type Inference
With the exception of
assertfrom the Java 1.4 days, new keywords always seem to make a big splash, and
varis no different.
Perhaps, the most curious thing about it is that it isn’t actually a reserved word , but something else entirely. But, there will be more on that in a moment.
varkeyword does is turn local variable assignments...
HashMap<String, String> ughThisIsSoVerbose = new HashMap<>();
var succinct = new HashMap<String, String>();
Simply put, as long as the construct on the right-hand side doesn’t require a on the left-hand side (like lambdas do), then, you can make all kinds of code easier to read, as shown below:
var tshirts = Lists.of("Baeldung Medium", "Java Large", "Lua Small"); var lines = Files.get(Paths.get("log/catalina.out")); var length = lines.count();
In other words, Java 10 introduces to the language. At compile time, it figures out the reference type based on the value type.
Now, we can append this to the growing list of type inferences that Java makes, already including .
This feature has been a . It was suggested as far back as 2001 and was closed at that time with the following comment by Gilad Bracha.
Humans benefit from the redundancy of the type declaration in two ways. First, the redundant type serves as valuable documentation — readers do not have to search for the declaration of
getMap()to find out what type it returns. Second, the redundancy allows the programmer to declare the intended type and, thereby, benefit from a cross-check performed by the compiler.
Times have changed, though, and the Java language is learning about the benefits of choice. For example, there are situations where
vars added succinctness and may make the code harder to read:
var x = someFunction();
The above snippet is completely valid Java 10 code, and it’s absolutely confusing to read.
It’s confusing, because it’s impossible for the reader to tell x ‘s type without tracking down
someFunction‘sreturn type. Similar complaints have been levied against dynamically-typed languages for years.
And, of course, this specific usage is precisely what Gilad warned the community about over 15 years ago.
varwith care, and remember that the goal is to write readable code.
It's Actually Not a Reserved Word
Don’t let folks tell you it is a reserved word. Under the hood,
varis a special new type in Java.
So, actually, you can still use var in other places of your code, say as a variable or class name. This allows Java to remain backward compatible with pre-Java 10 code that may have made the interesting choice of naming a variable or two "var."
And, there is a lot more to the story! Read up on using
varwith non-denotable types, as well as var's limitations surrounding polymorphism and lambda expressions in .
Unmodifiable Collection Enhancements
To introduce this next enhancement, consider the following Java puzzler. What is the value of v at the end of this program?
var vegetables = new ArrayList<>(Lists.of("Brocolli", "Celery", "Carrot")); var unmodifiable = Collections.unmodifiableList(vegetables); vegetables.set(0, "Radish"); var v = unmodifiable.get(0);
The answer, of course, is Radish . But, isn’t unmodifiable , well, unmodifiable?
Unmodifiable vs Unmodifiable V iew
Actually, according to Java 10’s updated
unmodifiableListreturns an unmodifiable view collection :
An unmodifiable view collection is a collection that is unmodifiable and is also a view onto a backing collection.
Examples of unmodifiable view collections are those returned by the
Collections.unmodifiableList, and related methods.
Note that changes to the backing collection might still be possible, and if they occur, they are visible through the unmodifiable view.
But, let’s say that you want something genuinely unmodifiable, what would you do?
Will the Real Unmodifiable Methods Please Stand Up?
Well, Java 10 adds two new APIs to make this possible, that is, to create collections that can’t be modified at all.
The first API allows unmodifiable copies to be made of collections by adding the
var unmodifiable = List.copyOf(vegetables);
That is different from wrapping a list in
copyOfperforms a shallow copy in iteration order. Changes to the
vegetableswon’t be manifested in
unmodifiablenow. Whereas, they are with our original approach.
The second API adds three new methods to the
Collectorsclass in . You can now stream directly into an unmodifiable collection using
var result = Arrays.asList(1, 2, 3, 4) .stream() .collect(Collectors.toUnmodifiableList());
Note that while these method names may remind you of
Collections.unmodifiableListand the like , these new methods produce genuinely unmodifiable lists, while
Collections.unmodifiableListreturns an unmodifiable view .
Java 9 made the Garbage-First Garbage Collector (G1GC) the default, replacing the Concurrent Mark-Sweep Garbage Collector (CMS). Java 10 introduces .
In Java 10, G1GC is getting a performance boost with the introduction of
full parallel processingduring a Full GC. This change won’t help the best-case performance times of the garbage collector, but it does significantly reduce the worst-case latencies. This makes pauses for garbage collection far less stressful on application performance.
When concurrent garbage collection falls behind, it triggers a Full GC collection. The performance improvement modifies the full collection so that it is no longer single-threaded, which significantly reduces the time needed to do a full garbage collection.
Application Class-Data Sharing
Java 5 introduced Class-Data Sharing (CDS) to improve startup times of smaller Java applications.
The general idea was that, when the JVM first launched, anything loaded by the bootstrap classloader was serialized and stored in a file on disk that could be reloaded on future launches of the JVM. This meant that multiple instances of the JVM shared the class metadata, so it wouldn’t have to load them all every time.
The shared-data cache meant a big improvement in startup times for smaller applications, because, in that case, the relative size of the core classes was larger than the application itself.
Java 10 extends this to include the system classloader and the platform classloader. To take advantage of that, you just need to add the following parameter:
Adding Your Own Classes to the Archive
But, the bigger change is that it into the Class-Data Sharing cache, too, possibly decreasing your startup times.
Basically, it is a three-step process. The first step is to create the list of classes that should be archived by starting up your application with the appropriate flags and indicating where you want the list to be stored:
java -Xshare:off -XX:+UseAppCDS -XX:DumpLoadedClassList=myapp.lst \ -cp $$CLASSPATH $$MAIN_CLASS
Then, with this list, you will create a CDS archive:
java -Xshare:dump -XX:+UseAppCDS -XX:SharedClassListFile=myapp.lst \ -XX:SharedArchiveFile=myapp.jsa \ -cp $$CLASSPATH
And, finally, run your app, using that archive:
java -Xshare:on -XX:+UseAppCDS -XX:SharedArchiveFile=hello.jsa \ -cp $$CLASSPATH $$MAIN_CLASS
New Just-in-Time Compiler
The Just-In-Time (JIT) Compiler is the part of Java that converts Java bytecode into machine code at runtime. The original JIT Compiler was written in C++ and is now considered quite difficult to modify.
Java 9 introduced a new experimental interface called the or JVMCI. The design of the new interface makes it possible to rewrite the JIT Compiler in pure Java. is the resulting JIT Compiler, .
Graal is currently an experimental JIT compiler. Only Linux/x64 machines can use it until future releases of Java. To enable Graal, add these flags to your command line arguments when starting the application:
And, keep in mind that the Graal team makes no promises in this first release that this compiler is any faster. The driving hope is that Graal will help evolve the JVMCI and make future maintenance tractable.
Among the performance improvements in the JVM, there is a subtle-but-powerful one referred to as .
During serviceability operations, like collecting for all threads or performing garbage collections, when the JVM needed to pause one thread, it needed to stop them all. Sometimes, these are referred to as “stop-the-world” pauses. This was due to the JVM wanting to create a global safe-point from which all application threads could begin again once the JVM was done.
In Java 10, though, the JVM can put an arbitrary number of threads into a safepoint, and threads may continue running after performing the prescribed “handshake." This resulted in the JVM being able to pause just one thread at a time, whereas before it had to pause them all.
To be clear, this isn’t a feature directly available to developers, but it is one everyone will enjoy.
A Forerunner for Big GC Changes
And, if you’re following closely, you’ll also see that this is related to an upcoming (and experimental) , which clocks GCs at only 10ms. It’s also a cousin to the very-cool as well.
The JVM now knows when it is running . This means the application now has accurate information about what the docker container allocates to memory, CPU, and other system resources.
Previously, the JVM queried the host operating system to get this information. This causes a problem when the docker container would actually like to advertise a different resource set.
For example, let’s say that you wanted to create a Java-based docker image where the running JVM was allocated 25 percent of the available memory specified by the container. On a box that has 2G of memory, running a container configured for 0.5G of memory, Java 9 and earlier would incorrectly calculate the Java process’s heap size based on the 2G number instead of 0.5G.
But, now, in Java 10, the JVM is capable of looking up this information from container control groups ( cgroups ), which is where Docker places these details.
There are command line options to specify how the JVM inside a Docker container allocates internal memory. For instance, to set the memory heap to the container group size and limit the number of processors, you could pass in these arguments:
With containers becoming a standard way to deploy services, this means developers now have a container-based way to control how their Java application uses resources.
Alternative Memory Allocation
Java is moving toward a more heterogeneous memory system by allowing users to specify .
An immediate use case is being able to allocate heap on a Non-Volatile DIMM (NVDIMM) module, which is commonly used in big Data applications.
Another use case is where many JVM processes are running on the same machine. In this case, it might be good to have processes that require a lower read latency map to DRAM and the remaining processes mapped to NVDIMM.
To use this, add this flag to your startup parameters:
For this parameter,
pathwould typically be a memory-mapped directory.
Easier SSL With OpenJDK
The open-source version of Java 10, , also received some great news regarding root certificates. Java ships with a key-store called
cacerts, which is a home for root certificates for Certificate Authorities that the JVM can use to perform SSL handshakes and the like. But, in OpenJDK, this key-store has always been empty, relying on the user to populate it.
This extra maintenance makes OpenJDK a less attractive choice if your application needs to open SSL sockets. However, Oracle decided in this release to issued by Oracle’s so that they could now be included in the open-source version of the JDK. Basically, this means that doing simple things, like communicating over HTTPS between your application and, say, a Google RESTful service, will be much simpler with OpenJDK.
Feel free to check out the difference by using
keytoolto list the certs in
keytool -cacerts -list
If you are using OpenJDK 9 or earlier, this will be empty, but with OpenJDK 10, it will be flush with certificates from Digicert, Comodo, Docusign, and many others.
The New Release Cycle
Aside from just a project management mechanism, Java 10 actually changes inside class files.
You’ve all seen an exception like this before:
Unsupported major.minor version 52.0 at java.lang.ClassLoader.defineClass1(Native Method) at java.lang.ClassLoader.defineClass(ClassLoader.java:791) ...
Of course, when you received this exception, if you were keeping track, you knew that this meant that you were trying to run a Java 8 library on a Java 7 JVM or earlier, because 52.0 meant Java 8, just like 51.0 meant Java 7.
Now, though, the new numbering system has semantic meaning. It will look something like this:
FEATURErefers to the version of Java. So, in Java 10’s case,
FEATUREis 10. It will increment every six-months, matching the new Java release cycle.
INTERIMis actually reserved for future “interim” cycles. For example, if Java wanted to start releasing faster than every six months. For the time being, it will always be 0.
UPDATEis a bit odd. It begins at 0 and one month after the last FEATURE release, it bumps up to 1. And, then, it increments every three months after that. So, that means that with Java 10, in April 2018,
UPDATEwas 1. In July 2018, it is 2, and in September, it is 3, incrementing until Java 10 is EOL.
PATCHis any release that needs to happen in between
UPDATEincrements, for example, critical bug fixes.
Additionally, version numbers remove trailing zeros. So, that means that the version string when Java 10 went live was simply 10 .
In April, Oracle released 10.0.1, and in July, it released 10.0.2 . You can check out on their website.
The Java 10 release includes additional bug fixes and performance improvements. The biggest performance boost was in the startup time of the JShell REPL tool. This will make working with the tool more responsive.
Java 10 is the first new release made of the JDK on the new 6-month release cycle.
Each release from now on will have fewer large features, but they will come much faster. This means that if a major feature misses a release, it will most likely be released only 6 months later. The original release cycle could have pushed a new feature out several years.
This time, some of the major features of the release were parallelized garbage collection, local variable type-inference, and the new release cycle numbering schema. Finally, for more details be sure to check out the official Java 10 .
以上为What’s New in Java 10?文章的全部内容，若您也有好的文章，欢迎与我们分享！