Previously, new versions of Java appeared rarely and with delays. Now Oracle successfully maintains its self-set rhythm of “new Java every six months.” So a few days ago, strictly on schedule, we finally received Java SE 11 and the implementation of the JDK (Java Development Kit). As always, the new version will be compatible with the old ones, and support for Java 11 will end no earlier than December 2026.
New features in Java SE 11 (visible to developers)
Recall that in Java, changes are made through the implementation of the JEP “JDK Enhancement Proposal”. JEP is a proposal to improve OpenJDK and may be approved, delayed, or rejected. That is, in essence, a collection of JEPs is a development strategy for OpenJDK. In square brackets before the new “feature” we will indicate the number of the corresponding JEP. [323] Local-Variable Syntax for Lambda Parameters - var syntax for lambda parameters Java 10 introduced the var keyword, which made it possible not to explicitly specify the type of a local variable. This simplified the code. JEP 323 expands the use of this syntax with lambda expressions. Simple example:
list.stream ()
.map ((var s) -> s.toLowerCase ())
.collect (Collectors.toList ());
As Simon Ritter , a well-known Java evangelist, writes, an experienced Java programmer will note that using var in this case may be unnecessary, since the code above can be replaced with the following:
list.stream ()
.map (s -> s.toLowerCase ())
.collect (Collectors.toList ());
Why, then, support var? There's just one special case - when you want to add an annotation to a lambda parameter. This can't be done without some type involved, and to avoid having to use an explicit type, we can simplify everything using var like this:
list.stream ()
.map ((@ Notnull var s) -> s.toLowerCase ())
.collect (Collectors.toList ());
[330] Launch Single-File Source-Code Programs Enhancing the Java launcher to launch a program as a single file with Java source code Java is often criticized for its verbose syntax and multi-step “ceremony” of launching even a trivial application. Sometimes this scares off newbies. To write an application that simply prints " Hello World! " ", you need to write a class with a public static void
main method and use the System.out.println
. Having done this, you must compile the code using javac . Finally, after this, you can launch the application, which will display the ill-fated greeting (of course, the integrated development environment, both IDEA and the one built into JavaRush , performs this “app launch magic” on its own - editor's note). Let's be honest: in most programming languages, the actual script for running programs looks much simpler. JEP 330 eliminates the need to compile a single-file application, so now if you use the command line, just type
java HelloWorld.java
The Java launcher will detect that the file contains Java source code and compile the code into a class file before executing it. You can place parameters after or before the source code file name. Those placed after the name are passed as parameters when the application is executed. Those placed before the name are passed as parameters to the Java launcher after the code is compiled. Compiler-specific options (such as classpath) will also be passed to javac for compilation. Example. Line:
java -classpath / home / foo / java Hello.java Bonjour
will be equivalent to these lines:
javac -classpath / home / foo / java Hello.java
java -classpath / home / foo / java Hello Bonjour
[321] HTTP Client (Standard) - HTTP Client API support has been standardized. JDK 9 introduced a new API to support the HTTP Client protocol (JEP 110) . Since JDK 9 also introduced the Java Platform Module System (JPMS) , this API was included as an incubator module (these are modules to provide developers with new APIs that have not yet become standard in Java SE, while the "live" APIs are being prepared for removal - developers can try out new APIs and try to provide feedback). Once the necessary changes are made (this API has been updated in JDK 10), the API can become part of the standard. So, the HTTP Client API is now officially included in Java SE 11 . This introduces a new module and package for the JDK, java.net.http . The main new types are: HttpClient HttpRequest HttpResponse WebSocket This API can be used synchronously or asynchronously. In asynchronous mode, CompletionFutures
and are used CompletionStages
. [320] Remove The Java EE and CORBA Modules With the introduction of the Java Platform Module System (JPMS) in the ninth version of Java, it became possible to split the monolithic rt.jar file into several modules. In addition, JPMS allows you to create a Java runtime environment that includes only the modules needed by your application, greatly reducing its size. With transparently defined module boundaries, it's much easier to remove obsolete parts of the Java API - that's what JEP 320 does. The java.se.ee metamodule includes six modules that will not be part of the Java SE 11 standard and will not be included in the JDK:
- corba
- transaction
- activation
- xml.bind
- xml.ws
- xml.ws.annotation
New APIs
A large number of new APIs in JDK 11 appeared thanks to the inclusion of the HTTP Client and Flight Recorder modules in the language standard . For a complete list of APIs, see the following comprehensive comparison of different versions of the JDK , compiled by Gunnar Morling. And in this note we will list some new methods that are not included in the java.net.http , jdk.jfr and java.security modules . java.lang.String Arguably one of the most important changes to String in the JDK 11 API, there are several useful new methods.boolean isBlank ()
: returns true if the string is empty or contains only spaces, false otherwise.Stream lines()
: Returns a stream of lines extracted from this string, separated by line terminators.String repeat (int)
: Returns a string whose value is the concatenation of that string repeated int times.String strip ()
: Returns a string with all spaces removed before or after the first non-space character.String stripLeading ()
: Returns a string with all spaces up to the first non-space character removed.String stripTrainling ()
: Returns a string with all spaces that occur after the last non-space character removed.
strip()
The method already did something similar trim ()
, but by spaces these methods mean different things. In case, trim()
only spaces are cut off, and in strip()
- also special characters, such as tabs. java.lang.StringBuffer java.lang.StringBuilder Both of these classes contain a new method compareTo ()
that accepts StringBuffer
/ StringBuilder
and returns int
. The lexical comparison method is similar to the new method compareTo() CharSequence
. java.io.ByteArrayOutputStream
void writeBytes (byte [])
: writes all bytes of the parameter to the java.io.FileReader output stream
Charset
. java.io.FileWriter Four new constructors that allow you to specify Charse
t. java.io.InputStream
io.InputStream nullInputStream ()
: returnsInputStream
, which does not read any bytes. How to use this method? You can think of it as something like /dev/null to throw away output you don't need, or to inject input that always returns zero bytes.
io.OutputStream nullOutputStream ()
io.Reader nullReader ()
io.Writer nullWriter ()
String toString (int)
: This is an overload of an existing method, but uses int instead of char.
int compare (CharSequence, CharSequence)
: lexicographically compares two instancesCharSequence
. Returns a negative value, zero, or a positive value if the first sequence is lexicographically less than, equal to, or greater than the second, respectively.
lang.Object clone ()
: Java evangelist Simon Ritter admits that this method confuses him. The class
Reference
does not implement an interface
Cloneable
and this method will always throw an exception
CloneNotSupportedException
. However, the expert suggests that this method will be useful for something in the future.
runFinalizersOnExit ()
has been removed from both of these classes, which may cause compatibility issues. java.lang.Thread No additional methods, we will only mention that destroy ()
they stop (Throwable)
were removed. However stop ()
, which takes no arguments, is still available. Please keep this in mind as there may be compatibility issues. java.nio.ByteBuffer java.nio.CharBuffer java.nio.DoubleBuffer java.nio.FloatBuffer java.nio.LongBuffer java.nio.ShortBuffer In all these classes, the language developers added a method mismatch ()
that finds and returns the relative index of the first mismatch between this buffer and a given buffer. java.nio.channels.SelectionKey
int interestOpsAnd (int)
int interestOpsOr (int)
int select (java.util.function.Consumer, long)
: Selects and executes an action on keys whose corresponding channels are ready for I/O operations. The long parameter is a timeout.int select (java.util.function.Consumer)
: works like the method above, but without the timeout.int selectNow (java.util.function.Consumer)
: works like the method above, only it is non-blocking.
String readString (Path)
: Reads all content from a file into a string, decoding bytes into characters using UTF-8 encoding .String readString (Path, Charset)
: Works like the method above, but decodes bytes into characters usingCharset
.Path writeString (Path, CharSequence, java.nio.file. OpenOption [])
: If you write a sequence of charactersCharSequence
to a file, those characters will be encoded into bytes (using UTF-8 ).Path writeString (Path, CharSequence, java.nio.file. Charset, OpenOption [])
: works like the method above, only the characters are encoded into bytes usingCharset
.
- Path(String, String[]): Returns the Path, transforming a pathstring or sequence of strings that when combined form a pathstring.
- Path (net.URI): Returns the path by transforming the URI.
Object [] toArray (java.util.function.IntFunction)
: Returns an array containing all the elements in this collection, using the provided generator function to distribute the returned array.
void forEach (java.util.function.Consumer)
: Performs the specified action on each Iterable element until all elements have been processed or the action throws an exception.boolean removeAll (java.util.Collection)
: Removes all elements of this collection that are also contained in the specified collection (optional operation).boolean removeIf (java.util.function.Predicate)
: Removes all elements of this collection that satisfy the given predicate.boolean retainAll (java.util.Collection)
: Preserves only the elements in this collection that are contained in the specified collection (optional operation).
long convert (java.time.Duration)
: Converts the given duration of time to this unit.
Predicate not(Predicate)
: returns a predicate that is the negation of the given predicate.
lines.stream ()
.filter (s ->! s.isBlank ())
can be converted to this:
lines.stream ()
.filter (Predicate.not (String :: ISBLANK))
and if we use static import, then this is what we get:
lines.stream ()
.filter (not(String :: ISBLANK))
java.util.Optional java.util.OptionalInt java.util.OptionalDouble java.util.OptionalLong
boolean isEmpty ()
: Returns true if there is no value , false otherwise .
Predicate asMatchPredicate ()
: Java expert Simon Ritter believes there may be a real JDK 11 API gem hidden here. This method creates a predicate that checks whether this pattern matches a given input string.
int deflate (ByteBuffer)
: Compresses the input data and fills the specified buffer with compressed data.int deflate (ByteBuffer, int)
: Compresses the input data and fills the specified buffer with compressed data. Returns the actual amount of compressed data.void setDictionary (ByteBuffer)
: Sets the given dictionary to be compressed into bytes in the given buffer. This is an overload of an existing method that can now accept aByteBuffer
, rather than a byte array.void setInput (ByteBuffer)
: Sets the input data to be compressed. It is also an overload of an existing method.
int inflate (ByteBuffer)
: Unpacks bytes into the specified buffer. Returns the actual number of uncompressed bytes.void setDictionary (ByteBuffer)
: Sets the given dictionary to the bytes in the given buffer. Is an overloaded form of an existing method.void setInput (ByteBuffer)
: Sets the input data for decompression. An overloaded form of an existing method.
void addAll (Collection)
: Adds all elements present in the collection.void addAll (int, Collection)
: Adds all elements present in the collection, starting at the specified index.
int [] getSelectedIndices ()
: Returns an array of all selected indexes in the selected model in ascending order.int getSelectedItemsCount ()
: Returns the number of selected items.
shell.JShellException getCause ()
: Returns the throwable reason in the execution client presented by this EvalException, or null if the reason does not exist or is unknown.
Non-developer features of Java 11
[181] Nest-Based Access Control Java and other languages support nested classes through inner classes. For this to work, the compiler must perform certain tricks. For example:
public class Outer {
private int outerInt;
class Inner {
public void printOuterInt() {
System.out.println("Outer int = " + outerInt);
}
}
}
The compiler modifies this to produce something like the following before compiling:
public class Outer {
private int outerInt;
public int access$000() {
return outerInt;
}
}
class Inner$Outer {
Outer outer;
public void printOuterInt() {
System.out.println("Outer int = " + outer.access$000());
}
}
Although logically the inner class is part of the same code as the outer class, it is compiled as a separate class. Therefore, this operation requires a synthetic join method that must be created by the compiler to provide access to the private field of the outer class. This JEP introduces the concept of nests, where two members of the same nest (Outer and Inner in our example) are nesting buddies. Two new attributes are defined for the class file format: NestHost and NestMembers . These changes are useful for other languages that support nested classes and bytecode. This function introduces three new methods for java.lang.Class : Class getNestHost () Class [] getNestMembers () boolean isNestmateOf (Class) [309] Dynamic Class-File Constants This JEP describes an extension to the class file format to support the new persistent pool form CONSTANT_Dynamic. The idea of a dynamic constant seems like an oxymoron, but essentially you can think of it as a final value in Java 11. The value of a pooling constant is not set at compile time (unlike other constants), but uses a bootstrap method to determine the value at lead time. Therefore the value is dynamic, but since its value is set only once, it is also constant. This feature is primarily aimed at people developing new languages and compilers that will generate bytecodes and class files as output to run on the JVM. [315] Improve Aarch64 Intrinsics This JEP was proposed by the Red Hat community. The JVM can now use more specialized instructions available in the Arm 64 instruction set. In particular, this improves the performance of the , methods sin ()
and cos ()
the java.lang.Mathlog ()
class . [318] Epsilon: A No-Op Garbage Collector As with JEP 315 , you can thank Red Hat for the introduction of the Epsilon garbage collector. Epsilon is unusual in that it doesn't actually collect garbage! When creating new objects, it allocates memory if needed, but does not reclaim space occupied by unregistered objects. “ What's the point? ", - you ask. It turns out that this “garbage collection” has two uses:
- First of all, this garbage collector is designed to ensure that new GC algorithms are evaluated in terms of their performance impact. The idea is to run a sample application with Epsilon and generate a set of metrics. The new garbage collection algorithm is enabled, the same tests are run, and then the results are compared.
- For very short tasks (think serverless functions in the cloud) where you can guarantee you won't exceed the memory allocated to the heap. This can improve performance by eliminating the overhead (including collecting statistics needed to decide whether to run the collector) in the application code. If heap space is exhausted, the JVM may be misconfigured in one of three ways:
- Normal is called
OutOfMemoryError
. - Perform a heap reset
- The JVM hard drive has failed and may be performing another task (such as starting a debugger).
- Normal is called
- Provides an API for producing and consuming data as events
- Provides a buffer mechanism and binary data format
- Allows customization and filtering of events
- Provide events for OS, JVM HotSpot and JDK libraries
GO TO FULL VERSION