Java 8 - 9 - 11

|
Divnesh BLOG

Java 8 Features

Java 8 provides following features for Java Programming:

  • Lambda expressions,
  • Method references,
  • Functional interfaces,
  • Stream API,
  • Default methods,
  • Base64 Encode Decode,
  • Static methods in interface,
  • Optional class,
  • Collectors class,
  • ForEach() method,
  • Parallel array sorting,
  • Nashorn JavaScript Engine,
  • Parallel Array Sorting,
  • Type and Repating Annotations,
  • IO Enhancements,
  • Concurrency Enhancements,
  • JDBC Enhancements etc.

  • forEach() method in Iterable interface
  • default and static methods in Interfaces
  • Functional Interfaces and Lambda Expressions
  • Java Stream API for Bulk Data Operations on Collections
  • Java Time API
  • Collection API improvements
  • Concurrency API improvements
  • Java IO improvements
  • Miscellaneous Core API improvements
Let’s have a brief look on these Java 8 features. I will provide some code snippets for better understanding, so if you want to run programs in Java 8, you will have to setup Java 8 environment by following steps.

Download JDK8 and install it. Installation is simple like other java versions. JDK installation is required to write, compile and run the program in Java.
Download latest Eclipse IDE, it provides support for java 8 now. Make sure your projects build path is using Java 8 library.
Learning Java? Nothing better than a video course trusted by over 1,70,000 students (yes, that many students). Follow this link to get heavy discount on the course.

forEach() method in Iterable interface
Whenever we need to traverse through a Collection, we need to create an Iterator whose whole purpose is to iterate over and then we have business logic in a loop for each of the elements in the Collection. We might get ConcurrentModificationException if iterator is not used properly.

Java 8 has introduced forEach method in java.lang.Iterable interface so that while writing code we focus on business logic only. forEach method takes java.util.function.Consumer object as argument, so it helps in having our business logic at a separate location that we can reuse. Let’s see forEach usage with simple example.

package com.journaldev.java8.foreach;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.function.Consumer;
import java.lang.Integer;

public class Java8ForEachExample {

public static void main(String[] args) {
//creating sample Collection
List<Integer> myList = new ArrayList<Integer>();
for(int i=0; i<10; i++) myList.add(i);
//traversing using Iterator
Iterator<Integer> it = myList.iterator();
while(it.hasNext()){
Integer i = it.next();
System.out.println("Iterator Value::"+i);
}
//traversing through forEach method of Iterable with anonymous class
myList.forEach(new Consumer<Integer>() {

public void accept(Integer t) {
System.out.println("forEach anonymous class Value::"+t);
}

});
//traversing with Consumer interface implementation
MyConsumer action = new MyConsumer();
myList.forEach(action);
}

}

//Consumer implementation that can be reused
class MyConsumer implements Consumer<Integer>{

public void accept(Integer t) {
System.out.println("Consumer impl Value::"+t);
}


}
The number of lines might increase but forEach method helps in having the logic for iteration and business logic at separate place resulting in higher separation of concern and cleaner code.


default and static methods in Interfaces
If you read forEach method details carefully, you will notice that it’s defined in Iterable interface but we know that interfaces can’t have method body. From Java 8, interfaces are enhanced to have method with implementation. We can use default and static keyword to create interfaces with method implementation. forEach method implementation in Iterable interface is:

default void forEach(Consumer<? super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }
We know that Java doesn’t provide multiple inheritance in Classes because it leads to Diamond Problem. So how it will be handled with interfaces now, since interfaces are now similar to abstract classes. The solution is that compiler will throw exception in this scenario and we will have to provide implementation logic in the class implementing the interfaces.

package com.journaldev.java8.defaultmethod;

@FunctionalInterface
public interface Interface1 {

void method1(String str);
default void log(String str){
System.out.println("I1 logging::"+str);
}
static void print(String str){
System.out.println("Printing "+str);
}
//trying to override Object method gives compile-time error as
//"A default method cannot override a method from java.lang.Object"
// default String toString(){
// return "i1";
// }
}
package com.journaldev.java8.defaultmethod;

@FunctionalInterface
public interface Interface2 {

void method2();
default void log(String str){
System.out.println("I2 logging::"+str);
}

}
Notice that both the interfaces have a common method log() with implementation logic.

package com.journaldev.java8.defaultmethod;

public class MyClass implements Interface1, Interface2 {

@Override
public void method2() {
}

@Override
public void method1(String str) {
}

//MyClass won't compile without having it's own log() implementation
@Override
public void log(String str){
System.out.println("MyClass logging::"+str);
Interface1.print("abc");
}
}
As you can see that Interface1 has static method implementation that is used in MyClass.log() method implementation. Java 8 uses default and static methods heavily in Collection API and default methods are added so that our code remains backward compatible.

If any class in the hierarchy has a method with the same signature, then default methods become irrelevant. Since any class implementing an interface already has Object as a superclass, if we have equals(), hashCode() default methods in the interface, it will become irrelevant. That’s why for better clarity, interfaces are not allowed to have Object default methods.

For complete details of interface changes in Java 8, please read Java 8 interface changes.



Functional Interfaces and Lambda Expressions
If you notice above interfaces code, you will notice @FunctionalInterface annotation. Functional interfaces are new concept introduced in Java 8. An interface with exactly one abstract method becomes Functional Interface. We don’t need to use @FunctionalInterface annotation to mark an interface as Functional Interface. @FunctionalInterface annotation is a facility to avoid accidental addition of abstract methods in the functional interfaces. You can think of it like @Override annotation and it’s best practice to use it. java.lang.Runnable with single abstract method run() is a great example of functional interface.

One of the major benefits of functional interface is the possibility to use lambda expressions to instantiate them. We can instantiate an interface with anonymous class but the code looks bulky.

Runnable r = new Runnable(){
@Override
public void run() {
System.out.println("My Runnable");
}};
Since functional interfaces have only one method, lambda expressions can easily provide the method implementation. We just need to provide method arguments and business logic. For example, we can write above implementation using lambda expression as:

Runnable r1 = () -> {
System.out.println("My Runnable");
};
If you have single statement in method implementation, we don’t need curly braces also. For example above Interface1 anonymous class can be instantiated using lambda as follows:

Interface1 i1 = (s) -> System.out.println(s);
i1.method1("abc");
So lambda expressions are a means to create anonymous classes of functional interfaces easily. There are no runtime benefits of using lambda expressions, so I will use it cautiously because I don’t mind writing a few extra lines of code.

A new package java.util.function has been added with bunch of functional interfaces to provide target types for lambda expressions and method references. Lambda expressions are a huge topic, I will write a separate article on that in the future.

You can read complete tutorial at Java 8 Lambda Expressions Tutorial.



Java Stream API for Bulk Data Operations on Collections
A new java.util.stream has been added in Java 8 to perform filter/map/reduce like operations with the collection. Stream API will allow sequential as well as parallel execution. This is one of the best features for me because I work a lot with Collections and usually with Big Data, we need to filter out them based on some conditions.

Collection interface has been extended with stream() and parallelStream() default methods to get the Stream for sequential and parallel execution. Let’s see their usage with simple example.

package com.journaldev.java8.stream;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;

public class StreamExample {

public static void main(String[] args) {
List<Integer> myList = new ArrayList<>();
for(int i=0; i<100; i++) myList.add(i);
//sequential stream
Stream<Integer> sequentialStream = myList.stream();
//parallel stream
Stream<Integer> parallelStream = myList.parallelStream();
//using lambda with Stream API, filter example
Stream<Integer> highNums = parallelStream.filter(p -> p > 90);
//using lambda in forEach
highNums.forEach(p -> System.out.println("High Nums parallel="+p));
Stream<Integer> highNumsSeq = sequentialStream.filter(p -> p > 90);
highNumsSeq.forEach(p -> System.out.println("High Nums sequential="+p));

}

}
If you will run above example code, you will get output like this:

High Nums parallel=91
High Nums parallel=96
High Nums parallel=93
High Nums parallel=98
High Nums parallel=94
High Nums parallel=95
High Nums parallel=97
High Nums parallel=92
High Nums parallel=99
High Nums sequential=91
High Nums sequential=92
High Nums sequential=93
High Nums sequential=94
High Nums sequential=95
High Nums sequential=96
High Nums sequential=97
High Nums sequential=98
High Nums sequential=99
Notice that parallel processing values are not in order, so parallel processing will be very helpful while working with huge collections.
Covering everything about Stream API is not possible in this post, you can read everything about Stream API at Java 8 Stream API Example Tutorial.


Java Time API
It has always been hard to work with Date, Time and Time Zones in java. There was no standard approach or API in java for date and time in Java. One of the nice addition in Java 8 is the java.time package that will streamline the process of working with time in java.

Just by looking at Java Time API packages, I can sense that it will be very easy to use. It has some sub-packages java.time.format that provides classes to print and parse dates and times and java.time.zone provides support for time-zones and their rules.

The new Time API prefers enums over integer constants for months and days of the week. One of the useful class is DateTimeFormatter for converting DateTime objects to strings.

For complete tutorial, head over to Java Date Time API Example Tutorial.


Collection API improvements
We have already seen forEach() method and Stream API for collections. Some new methods added in Collection API are:

Iterator default method forEachRemaining(Consumer action) to perform the given action for each remaining element until all elements have been processed or the action throws an exception.
Collection default method removeIf(Predicate filter) to remove all of the elements of this collection that satisfy the given predicate.
Collection spliterator() method returning Spliterator instance that can be used to traverse elements sequentially or parallel.
Map replaceAll(), compute(), merge() methods.
Performance Improvement for HashMap class with Key Collisions

Concurrency API improvements
Some important concurrent API enhancements are:

ConcurrentHashMap compute(), forEach(), forEachEntry(), forEachKey(), forEachValue(), merge(), reduce() and search() methods.
CompletableFuture that may be explicitly completed (setting its value and status).
Executors newWorkStealingPool() method to create a work-stealing thread pool using all available processors as its target parallelism level.

Java IO improvements
Some IO improvements known to me are:

Files.list(Path dir) that returns a lazily populated Stream, the elements of which are the entries in the directory.
Files.lines(Path path) that reads all lines from a file as a Stream.
Files.find() that returns a Stream that is lazily populated with Path by searching for files in a file tree rooted at a given starting file.
BufferedReader.lines() that return a Stream, the elements of which are lines read from this BufferedReader.

Miscellaneous Core API improvements
Some misc API improvements that might come handy are:

  • ThreadLocal static method withInitial(Supplier supplier) to create instance easily.
  • Comparator interface has been extended with a lot of default and static methods for natural ordering, reverse order etc.
  • min(), max() and sum() methods in Integer, Long and Double wrapper classes.
  • logicalAnd(), logicalOr() and logicalXor() methods in Boolean class.
  • ZipFile.stream() method to get an ordered Stream over the ZIP file entries. Entries appear in the Stream in the order they appear in the central directory of the ZIP file.
  • Several utility methods in Math class.
  • jjs command is added to invoke Nashorn Engine.
  • jdeps command is added to analyze class files
  • JDBC-ODBC Bridge has been removed.
  • PermGen memory space has been removed

Lambda expressions
Lambda expression helps us to write our code in functional style. It provides a clear and concise way to implement SAM interface(Single Abstract Method) by using an expression. It is very useful in collection library in which it helps to iterate, filter and extract data.


Java 9 Features : 
  • Java 9 REPL (JShell)
  • Factory Methods for Immutable List, Set, Map and Map.Entry
  • Private methods in Interfaces
  • Java 9 Module System
  • Process API Improvements
  • Try With Resources Improvement
  • CompletableFuture API Improvements
  • Reactive Streams
  • Diamond Operator for Anonymous Inner Class
  • Optional Class Improvements
  • Stream API Improvements
  • Enhanced @Deprecated annotation
  • HTTP 2 Client
  • Multi-Resolution Image API
  • Miscellaneous Java 9 Features
Oracle Corporation is going to release Java SE 9 around the end of March 2017. In this post, I’m going to discuss “Java 9 Features” briefly with some examples.


Java 9 REPL (JShell)
Oracle Corp has introduced a new tool called “jshell”. It stands for Java Shell and also known as REPL (Read Evaluate Print Loop). It is used to execute and test any Java Constructs like class, interface, enum, object, statements etc. very easily.

We can download JDK 9 EA (Early Access) software from https://jdk9.java.net/download/


G:\>jshell
|  Welcome to JShell -- Version 9-ea
|  For an introduction type: /help intro


jshell> int a = 10
a ==> 10

jshell> System.out.println("a value = " + a )
a value = 10
If you want to know more about REPL tool, Please go through Java 9 REPL Basics (Part-1) and Java 9 REPL Features (Part-2).

Factory Methods for Immutable List, Set, Map and Map.Entry
Oracle Corp has introduced some convenient factory methods to create Immutable List, Set, Map and Map.Entry objects. These utility methods are used to create empty or non-empty Collection objects.

In Java SE 8 and earlier versions, We can use Collections class utility methods like unmodifiableXXX to create Immutable Collection objects. For instance, if we want to create an Immutable List, then we can use Collections.unmodifiableList method.

However, these Collections.unmodifiableXXX methods are a tedious and verbose approach. To overcome those shortcomings, Oracle Corp has added a couple of utility methods to List, Set and Map interfaces.

List and Set interfaces have “of()” methods to create an empty or no-empty Immutable List or Set objects as shown below:

Empty List Example

List immutableList = List.of();
Non-Empty List Example

List immutableList = List.of("one","two","three");
The Map has two sets of methods: of() methods and ofEntries() methods to create an Immutable Map object and an Immutable Map.Entry object respectively.

Empty Map Example

jshell> Map emptyImmutableMap = Map.of()
emptyImmutableMap ==> {}
Non-Empty Map Example

jshell> Map nonemptyImmutableMap = Map.of(1, "one", 2, "two", 3, "three")
nonemptyImmutableMap ==> {2=two, 3=three, 1=one}
If you want to read more about these utility methods, please go through the following links:

Java 9 Factory Methods for Immutable List
Java 9 Factory Methods for Immutable Set
Java 9 Factory Methods for Immutable Map and Map.Entry

Private methods in Interfaces
In Java 8, we can provide method implementation in Interfaces using Default and Static methods. However we cannot create private methods in Interfaces.

To avoid redundant code and more re-usability, Oracle Corp is going to introduce private methods in Java SE 9 Interfaces. From Java SE 9 onwards, we can write private and private static methods too in an interface using a ‘private’ keyword.

These private methods are like other class private methods only, there is no difference between them.

public interface Card{

  private Long createCardID(){
    // Method implementation goes here.
  }

  private static void displayCardDetails(){
    // Method implementation goes here.
  }

}
If you want to read more about this new feature, please go through this link: Java 9 Private methods in Interface.

Java 9 Module System
One of the big changes or java 9 feature is the Module System. Oracle Corp is going to introduce the following features as part of Jigsaw Project.
  • Modular JDK
  • Modular Java Source Code
  • Modular Run-time Images
  • Encapsulate Java Internal APIs
  • Java Platform Module System
Before Java SE 9 versions, we are using Monolithic Jars to develop Java-Based applications. This architecture has a lot of limitations and drawbacks. To avoid all these shortcomings, Java SE 9 is coming with the Module System.

JDK 9 is coming with 92 modules (may change in final release). We can use JDK Modules and also we can create our own modules as shown below:

Simple Module Example

module com.foo.bar { }
Here we are using ‘module’ to create a simple module. Each module has a name, related code, and other resources.

To read more details about this new architecture and hands-on experience, please go through my original tutorials here:

Java 9 Module System Basics
Java 9 Module Examples using command prompt
Java 9 Hello World Module Example using Eclipse IDE

Process API Improvements
Java SE 9 is coming with some improvements in Process API. They have added couple new classes and methods to ease the controlling and managing of OS processes.

Two new interfcase in Process API:
  • java.lang.ProcessHandle
  • java.lang.ProcessHandle.Info
Process API example

 ProcessHandle currentProcess = ProcessHandle.current();
 System.out.println("Current Process Id: = " + currentProcess.getPid());

Try With Resources Improvement
We know, Java SE 7 has introduced a new exception handling construct: Try-With-Resources to manage resources automatically. The main goal of this new statement is “Automatic Better Resource Management”.

Java SE 9 is going to provide some improvements to this statement to avoid some more verbosity and improve some Readability.


Java SE 7 example

void testARM_Before_Java9() throws IOException{
 BufferedReader reader1 = new BufferedReader(new FileReader("journaldev.txt"));
 try (BufferedReader reader2 = reader1) {
   System.out.println(reader2.readLine());
 }
}
Java 9 example

void testARM_Java9() throws IOException{
 BufferedReader reader1 = new BufferedReader(new FileReader("journaldev.txt"));
 try (reader1) {
   System.out.println(reader1.readLine());
 }
}
To read more about this new feature, please go through my original tutorial at: Java 9 Try-With-Resources Improvements

CompletableFuture API Improvements
In Java SE 9, Oracle Corp is going to improve CompletableFuture API to solve some problems raised in Java SE 8. They are going add to support some delays and timeouts, some utility methods and better sub-classing.

Executor exe = CompletableFuture.delayedExecutor(50L, TimeUnit.SECONDS);
Here delayedExecutor() is a static utility method used to return a new Executor that submits a task to the default executor after the given delay.

Reactive Streams
Nowadays, Reactive Programming has become very popular in developing applications to get some beautiful benefits. Scala, Play, Akka, etc. Frameworks have already integrated Reactive Streams and getting many benefits. Oracle Corps is also introducing new Reactive Streams API in Java SE 9.

Java SE 9 Reactive Streams API is a Publish/Subscribe Framework to implement Asynchronous, Scalable and Parallel applications very easily using Java language.

Java SE 9 has introduced the following API to develop Reactive Streams in Java-based applications.

java.util.concurrent.Flow
java.util.concurrent.Flow.Publisher
java.util.concurrent.Flow.Subscriber
java.util.concurrent.Flow.Processor
Read more at Java 9 Reactive Streams.

Diamond Operator for Anonymous Inner Class
We know, Java SE 7 has introduced one new feature: Diamond Operator to avoid redundant code and verbosity, to improve readability. However, in Java SE 8, Oracle Corp (Java Library Developer) has found that some limitations in the use of Diamond operator with Anonymous Inner Class. They have fixed those issues and going to release them as part of Java 9.

  public List getEmployee(String empid){
     // Code to get Employee details from Data Store
     return new List(emp){ };
  }
Here we are using just “List” without specifying the type parameter.

Optional Class Improvements
In Java SE 9, Oracle Corp has added some useful new methods to java.util.Optional class. Here I’m going to discuss about one of those methods with some simple example: stream method

If a value present in the given Optional object, this stream() method returns a sequential Stream with that value. Otherwise, it returns an empty Stream.

They have added “stream()” method to work on Optional objects lazily as shown below:

Stream<Optional> emp = getEmployee(id)
Stream empStream = emp.flatMap(Optional::stream)
Here Optional.stream() method is used to convert a Stream of Optional of Employee object into a Stream of Employee so that we can work on this result lazily in the result code.

To understand more about this feature with more examples and to read more new methods added to Optional class, please go through my original tutorial at: Java SE 9: Optional Class Improvements

Stream API Improvements
In Java SE 9, Oracle Corp has added four useful new methods to java.util.Stream interface. As Stream is an interface, all those new implemented methods are default methods. Two of them are very important: dropWhile and takeWhile methods

If you are familiar with Scala Language or any Functions programming language, you will definitely know about these methods. These are very useful methods in writing some functional style code. Let us discuss the takeWhile utility method here.

This takeWhile() takes a predicate as an argument and returns a Stream of the subset of the given Stream values until that Predicate returns false for the first time. If the first value does NOT satisfy that Predicate, it just returns an empty Stream.

jshell> Stream.of(1,2,3,4,5,6,7,8,9,10).takeWhile(i -> i < 5 )
                 .forEach(System.out::println);
1
2
3
4
To read more about takeWhile and dropWhile methods and other new methods, please go through my original tutorial at: Java SE 9: Stream API Improvements

Enhanced @Deprecated annotation
In Java SE 8 and earlier versions, @Deprecated annotation is just a Marker interface without any methods. It is used to mark a Java API that is a class, field, method, interface, constructor, enum etc.

In Java SE 9, Oracle Corp has enhanced @Deprecated annotation to provide more information about deprecated API and also provide a Tool to analyze an application’s static usage of deprecated APIs. They have add two methods to this Deprecated interface: forRemoval and since to serve this information.

HTTP 2 Client
In Java SE 9, Oracle Corp is going to release New HTTP 2 Client API to support HTTP/2 protocol and WebSocket features. As existing or Legacy HTTP Client API has numerous issues (like supports HTTP/1.1 protocol and does not support HTTP/2 protocol and WebSocket, works only in Blocking mode and lot of performance issues.), they are replacing this HttpURLConnection API with new HTTP client.

They are going to introduce a new HTTP 2 Client API under the “java.net.http” package. It supports both HTTP/1.1 and HTTP/2 protocols. It supports both Synchronous (Blocking Mode) and Asynchronous Modes. It supports Asynchronous Mode using the WebSocket API.

We can see this new API at https://download.java.net/java/jdk9/docs/api/java/net/http/package-summary.html

HTTP 2 Client Example

jshell> import java.net.http.*

jshell> import static java.net.http.HttpRequest.*

jshell> import static java.net.http.HttpResponse.*

jshell> URI uri = new URI("https://rams4java.blogspot.co.uk/2016/05/java-news.html")
uri ==> https://rams4java.blogspot.co.uk/2016/05/java-news.html

jshell> HttpResponse response = HttpRequest.create(uri).body(noBody()).GET().response()
response ==> java.net.http.HttpResponseImpl@79efed2d

jshell> System.out.println("Response was " + response.body(asString()))
Please go through my original tutorial at: Java SE 9: HTTP 2 Client to understand HTTP/2 protocol & WebSocket, Benefits of new API and Drawbacks of OLD API with some useful examples.

Multi-Resolution Image API
In Java SE 9, Oracle Corp is going to introduce a new Multi-Resolution Image API. Important interface in this API is MultiResolutionImage . It is available in java.awt.image package.

MultiResolutionImage encapsulates a set of images with different Height and Widths (that is different resolutions) and allows us to query them with our requirements.

Miscellaneous Java 9 Features
In this section, I will just list out some miscellaneous Java SE 9 New Features. I’m NOT saying these are less important features. They are also important and useful to understand them very well with some useful examples.

As of now, I did not get enough information about these features. That’s why I am going to list them here for a brief understanding. I will pick up these features one by one and add to the above section with a brief discussion and example. And finally write a separate tutorial later.
  • GC (Garbage Collector) Improvements
  • Stack-Walking API
  • Filter Incoming Serialization Data
  • Deprecate the Applet API
  • Indify String Concatenation
  • Enhanced Method Handles
  • Java Platform Logging API and Service
  • Compact Strings
  • Parser API for Nashorn
  • Javadoc Search
  • HTML5 Javadoc

Java 11 Features :
  • Running Java File with single command
  • New utility methods in String class
  • Local-Variable Syntax for Lambda Parameters
  • Nested Based Access Control
  • JEP 321: HTTP Client
  • Reading/Writing Strings to and from the Files
  • JEP 328: Flight Recorder

4.1) Running Java File with single command
One major change is that you don’t need to compile the java source file with javac tool first. You can directly run the file with java command and it implicitly compiles.
This feature comes under JEP 330.

Following is a sneak peek at the new methods of Java String class introduced in Java 11:

4.2) Java String Methods
isBlank() – This instance method returns a boolean value. Empty Strings and Strings with only white spaces are treated as blank.

import java.util.*;

public class Main {
    public static void main(String[] args) throws Exception {
        // Your code here!
        
        System.out.println(" ".isBlank()); //true
        
        String s = "Anupam";
        System.out.println(s.isBlank()); //false
        String s1 = "";
        System.out.println(s1.isBlank()); //true
    }
}

lines()

This method returns a stream of strings, which is a collection of all substrings split by lines.

import java.util.stream.Collectors;

public class Main {
    public static void main(String[] args) throws Exception {
        
        String str = "JD\nJD\nJD"; 
        System.out.println(str);
        System.out.println(str.lines().collect(Collectors.toList()));
    }
}
The output of the above code is:
JD
JD
JD
[JD,JD,JD]
java 11 string lines method

strip(), stripLeading(), stripTrailing()

strip() – Removes the white space from both, beginning and the end of string.

But we already have trim(). Then what’s the need of strip()?
strip() is “Unicode-aware” evolution of trim().

When trim() was introduced, Unicode wasn’t evolved. Now, the new strip() removes all kinds of whitespaces leading and trailing(check the method Character.isWhitespace(c) to know if a unicode is whitespace or not)

An example using the above three methods is given below:

public class Main {
    public static void main(String[] args) throws Exception {
        // Your code here!
        
        String str = " JD "; 
        System.out.print("Start");
        System.out.print(str.strip());
        System.out.println("End");
        
        System.out.print("Start");
        System.out.print(str.stripLeading());
        System.out.println("End");
        
        System.out.print("Start");
        System.out.print(str.stripTrailing());
        System.out.println("End");
    }
}
The output in the console from the above code is:
StartJDEnd
StartJD End
Start JDEnd

java 11 string strip method

repeat(int)

The repeat method simply repeats the string that many numbers of times as mentioned in the method in the form of an int.

public class Main {
    public static void main(String[] args) throws Exception {
        // Your code here!
        
        String str = "=".repeat(2);
        System.out.println(str); //prints ==
    }
}
4.3) Local-Variable Syntax for Lambda Parameters
JEP 323, Local-Variable Syntax for Lambda Parameters is the only language feature release in Java 11.
In Java 10, Local Variable Type Inference was introduced. Thus we could infer the type of the variable from the RHS – var list = new ArrayList<String>();

JEP 323 allows var to be used to declare the formal parameters of an implicitly typed lambda expression.

We can now define :

(var s1, var s2) -> s1 + s2
This was possible in Java 8 too but got removed in Java 10. Now it’s back in Java 11 to keep things uniform.

But why is this needed when we can just skip the type in the lambda?
If you need to apply an annotation just as @Nullable, you cannot do that without defining the type.

Limitation of this feature – You must specify the type var on all parameters or none.
Things like the following are not possible:

(var s1, s2) -> s1 + s2 //no skipping allowed
(var s1, String y) -> s1 + y //no mixing allowed

var s1 -> s1 //not allowed. Need parentheses if you use var in lambda.
4.4) Nested Based Access Control
Before Java 11 this was possible:

public class Main {
 
    public void myPublic() {
    }
 
    private void myPrivate() {
    }
 
    class Nested {
 
        public void nestedPublic() {
            myPrivate();
        }
    }
}
private method of the main class is accessible from the above-nested class in the above manner.
But if we use Java Reflection, it will give an IllegalStateException.

Method method = ob.getClass().getDeclaredMethod("myPrivate");
method.invoke(ob);
Java 11 nested access control addresses this concern in reflection.
java.lang.Class introduces three methods in the reflection API: getNestHost(), getNestMembers(), and isNestmateOf().

4.5) JEP 309: Dynamic Class-File Constants
The Java class-file format now extends support a new constant pool form, CONSTANT_Dynamic. The goal of this JEP is to reduce the cost and disruption of developing new forms of materializable class-file constraints, by creating a single new constant-pool form that can be parameterized with user-provided behavior.
This enhances performance

4.6) JEP 318: Epsilon: A No-Op Garbage Collector
Unlike the JVM GC which is responsible for allocating memory and releasing it, Epsilon only allocates memory.
It allocates memory for the following things:

  • Performance testing.
  • Memory pressure testing.
  • VM interface testing.
  • Extremely short lived jobs.
  • Last-drop latency improvements.
  • Last-drop throughput improvements.
Now Elipson is good only for test environments. It will lead to OutOfMemoryError in production and crash the applications.

The benefit of Elipson is no memory clearance overhead. Hence it’ll give an accurate test result of performance and we can no longer GC for stopping it.

Note: This is an experimental feature.

4.7) JEP 320: Remove the Java EE and CORBA Modules
The modules were already deprecated in Java 9. They are now completely removed.

Following packages are removed: java.xml.ws, java.xml.bind, java.activation, java.xml.ws.annotation, java.corba, java.transaction, java.se.ee, jdk.xml.ws, jdk.xml.bind

4.8) JEP 328: Flight Recorder
Flight Recorder which earlier used to be a commercial add-on in Oracle JDK is now open-sourced since Oracle JDK is itself not free anymore.

JFR is a profiling tool used to gather diagnostics and profiling data from a running Java application.
Its performance overhead is negligible and that’s usually below 1%. Hence it can be used in production applications.

4.9) JEP 321: HTTP Client
Java 11 standardizes the Http CLient API.
The new API supports both HTTP/1.1 and HTTP/2. It is designed to improve the overall performance of sending requests by a client and receiving responses from the server. It also natively supports WebSockets.

4.10) Reading/Writing Strings to and from the Files
Java 11 strives to make reading and writing of String convenient.
It has introduced the following methods for reading and writing to/from the files:

readString()
writeString()
Following code showcases an example of this

Path path = Files.writeString(Files.createTempFile("test", ".txt"), "This was posted on JD");
System.out.println(path);
String s = Files.readString(path);
System.out.println(s); //This was posted on JD

4.11) JEP 329: ChaCha20 and Poly1305 Cryptographic Algorithms
Java 11 provides ChaCha20 and ChaCha20-Poly1305 cipher implementations. These algorithms will be implemented in the SunJCE provider.

4.12) JEP 315: Improve Aarch64 Intrinsics
Improve the existing string and array intrinsics, and implement new intrinsics for the java.lang.Math sin, cos, and log functions, on AArch64 processors.

4.13) JEP 333: ZGC: A Scalable Low-Latency Garbage Collector (Experimental)
Java 11 has introduced a low latency GC. This is an experimental feature.
It’s good to see that Oracle is giving importance to GC’s.

4.14) JEP 335: Deprecate the Nashorn JavaScript Engine
Nashorn JavaScript script engine and APIs are deprecated thereby indicating that they will be removed in the subsequent releases.

5. Conclusion
We’ve gone through the important features and updates provided in Java 11. See you soon when Java 12 releases.

Featured Post

HTML cheetsheet

List: Link tgs Dropdown

Popular Post

(C) Copyright 2018, All rights resrved InShortView. Template by colorlib