Java 9 Features

java

By
Narendran Solai Sridharan

Features by Categories

java 9 features

Notable Categories

  • Tooling

  • API Enhancements

  • Important Under the hood Changes

  • New Standards

  • References

Tooling

Important New Tools

  • jshell

  • jdeps

  • jlink

  • jmod

  • jdeprscan

jshell

REPL - Read, Evaluate, Print and Loop

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

jshell> 3 + 4 * 7
$1 ==> 31

jshell> int add(int a, int b) {
...>   return a+b;
...> }
|  created method add(int,int)

jshell> add(25, $1)
$3 ==> 56

jdeps

"C:\Program Files\Java\jdk-9\bin\jdeps"
-summary
guava-23.0.jar

"C:\Program Files\Java\jdk-9\bin\jdeps"
--dot-output
-summary
guava-23.0.jar

jmod

"C:\Program Files\Java\jdk-9\bin\jmod"
create --class-path target\classes
target\jmods\org.wildcraft.tooling.jmod

jdeprscan

"C:\Program Files\Java\jdk-9\bin\jdeprscan"
guava-23.0.jar

"C:\Program Files\Java\jdk-9\bin\jdeprscan"
--release 9
--list

Tool Enhancements

  • javac

  • java

  • jar

  • javadoc

javadoc

Provides HTML 5 support and search facilities.

javadoc html5 example

Java Artifacts

  • jmod

  • jlink & jimage

  • MR jar for Java library release management

MR jar

JAR content root
  A.class
  B.class
  C.class
  D.class
  META-INF
     MANIFEST.MF
     versions
        9
           A.class
           B.class
        10
           A.class

API Enhancements

There are various small changes. Even if we don’t leverage JPMS, once we onboard Java 9, we can make use of these small enhancements immediately.

Collection Factories

/* Comment sections would break ... */
List<Integer> listOfNumbers = List.of(1, 2, 3, 4, 5
                                        /*, null*/);

Set<Integer> setOfNumbers = Set.of(1, 2, 3, 4, 5/*, 1*/);

Map<String, String> mapOfString =
    Map.of("key1", "value1", "key2", "value2");

Map<String, String> moreMapOfString =
    Map.ofEntries(
        Map.entry("key1", "value1"),
        Map.entry("key2", "value2")/*,
        Map.entry("key1", "value3")*/
);

Stream Enhancements

Stream.of("a", "b", "c", "", "e")
                .takeWhile(s -> !s.isEmpty())
                .forEach(System.out::print);

Stream.of("a", "b", "c", "de", "f")
                .dropWhile(s -> s.length() <= 1)
                .forEach(System.out::print);

Stream.iterate(1, i -> 2 * i)
                .filter(i->i<=10)
                .forEach(System.out::println);

Stream.iterate(1, i -> i <= 10, i -> 2 * i)
                .forEach(System.out::println);

Try with Resource

FileReader fileReader
                  = new FileReader(new File(fileURI));
BufferedReader bufferedReader
                  = new BufferedReader(fileReader);
try (fileReader; bufferedReader) {

    String line = "";
    while ((line = bufferedReader.readLine()) != null) {
        fileContent =line;
    }
}

Diamond Operator

<T> Box<T> createBox(T content) {
    // we have to put the `T` here :(
    return new Box<T>(content) { };
}

<T> Box<T> createBox(T content) {
    // Java 9 can infer `T`
    // because it is a denotable type
    return new Box<>(content) { };
}

Box<?> createCrazyBox(Object content) {
    List<?> innerList = Arrays.asList(content);
    // we can't do the following
    // because the inferred type is non-denotable
    return new Box<List<?>>(innerList) { };
}

Deprecated Annotation Enhancement

@Deprecated(since = "3.0")
public class Asset {

    @Deprecated(since = "1.0", forRemoval=true)
    public void getAssertValue() {

    }
}

SafeVarargs

It is now applicable to public non final methods.

@SafeVarargs
private <T> Optional<T> privateNonStatic(T... args) {
    if (args.length == 0)
        return Optional.empty();
    else
        return Optional.of(args[0]);
}

Important Under the hood Changes

Compact String

Default GC Collector G1

GC multiple partitions with pointers

New Standards

Reactive Programming Flow API

reactive programming

HTTP API

/**
 * The HTTP API functions asynchronously
 * and synchronously. In
 * asynchronous mode,
 * work is done in threads (ExecutorService).
 */
public static void main(String[] args) throws Exception {
  HttpClient.getDefault()
    .request(URI.create("https://www.exxcellent.de"))
    .GET()
    .responseAsync() // CompletableFuture :D
    .thenAccept(httpResponse ->
        out.println(httpResponse
        .body(HttpResponse.asString()))
    );
  Thread.sleep(999); // Give worker thread some time.
}

References