Migration to Java 8, 9, 10, 11

Augusto Alonso de la Cruz Jiménez
@augustoalonso1

It is not the strongest of the species that survives, nor the most intelligent that survives. It is the one that is most adaptable to change.

Charles Darwin. On the Origin of Species. 1859

Java versions

  • 23 jun 1996 - JDK 1.0
  • 19 ene 1997 - JDK 1.1
  • 08 dic 1998 - J2SE 1.2
  • 08 may 2000 - J2SE 1.3
  • 06 feb 2002 - J2SE 1.4
  • 30 sep 2004 - J2SE 5.0
  • 11 dic 2006 - Java SE 6
  • 28 jul 2011 - Java SE 7
  • 18 mar 2014 - Java SE 8
  • 22 sep 2017 - Java SE 9
  • 20 mar 2018 - Java SE 10
  • 25 sep 2018 - Java SE 11

J2SE 5.0

  • Generics
  • Annotations
  • Autoboxing/unboxing
  • Enumerations
  • Varargs
  • for each
  • Static imports

 

Oracle issued 85 public updates to this version.

Java SE 6

  • Scripting Language Support Rhino
  • Performance improvements
  • Autoboxing/unboxing
  • Improved support for JAX-WS, JAXB
  • JDBC 4.0 support

 

There were 211 updates for this version of Java

Java SE 7

  • JVM support for dynamic languages
  • Strings in switch
  • Automatic resource management in try-statement
  • Diamond operator
  • Underscores in numeric literals
  • Multicatch
  • Concurrency utilities
  • NIO 2

 

There were 201 updates for this version of Java

Java SE 8

  • Lamdas
  • Stream API
  • Default methods. Multiple inheritance of type and behaviour (but not state)
  • Nashorn engine
  • Repeating annotations
  • Date and Time API
  • Remove Perm Gen

 

There were 192 updates for this version of Java

Java SE 9

  • Jigsaw
  • jshell
  • AoT
  • Reactive Streams
  • jlink Custom runtime images

 

There were 3 updates for this version of Java

Java SE 10

  • Local-Variable Type Inference
  • Parallel Full GC for G1

 

There were 3 updates for this version of Java

Java SE 11

  • Dynamic Class-File Constants
  • Epsilon: A No-Op Garbage Collector
  • Local-Variable Syntax for Lambda Parameters
  • HTTP Client (Standard)
  • TLS 1.3
  • Java EE libraries have been removed from JDK

 

There were 3 updates for this version of Java

Are you using Java 7?

  • Diamond Operator
  • Strings in switch statements
  • try with resources
  • Numeric literals with underscores
  • Multicatch exception
  • NIO 2.0

Diamond Operator

Before Java :

 

List<Map<String, String>> list = new ArrayList<Map<String, String>>();
Map<String, Map<String, String>> cache = new HashMap<String, Map<String, String>>();
   

 

 

Java 7+ :

 

List<Map<String, String>> list = new ArrayList<>();
Map<String, Map<String, String>> cache = new HashMap<>();

 

Diamond Operator

Not limited to one-line declaration:

 

public class Test {

    private List<Map<String, Object>> books;

    public Test() {
        //Instance variable level
        this.books = new ArrayList<>(); 
    }
    
    public List<String> titles() {
        List<String> titles;
        titles = new ArrayList<>(); //Local variable level
        return titles;
    }
}

Strings in switch statements

public class Operation {

    public void executeOperation(int operation) {  
        switch (operation) {
            case 1: add(); break;
            case 2: update(); break;
            case 3: delete(); break;
            case 4: view(); break;
            default: throw new UnsupportedOperationException();
        }
    }

    ...//methods add(), update(), delete(), view()
}

 

Java7+

public void executeOperation(String operation) {

    switch (operation) {
        case "ADD": add(); break;
        case "UPDATE": update(); break;
        case "DELETE": delete(); break;
        case "VIEW": view(); break;
        default: throw new UnsupportedOperationException();
    }
}

 

 

try-with-resources (ARM)

Makes the code more robust and cuts down the lines of code

Before Java7

Scanner scanner = null;

try {
    scanner = new Scanner(new File("test.txt"));
    while (scanner.hasNext()) {
        System.out.println(scanner.nextLine());
    }
} catch (FileNotFoundException e) {
    e.printStackTrace();
} finally {
    if (scanner != null) {
        scanner.close();
    }
}

 

Java7+

try (Scanner scanner = new Scanner(new File("test.txt"))) {
    while (scanner.hasNext()) {
        System.out.println(scanner.nextLine());
    }
} catch (FileNotFoundException fnfe) {
    fnfe.printStackTrace();
}

Numerical literals with underscores

In Java 7+, any number of underscores (_) can appear anywhere between digits in a numerical literal, improving readability of code.

 

Before Java7

long creditCardNumber = 1234567890123456L;
long socialSecurityNumber = 999999999L;
byte nybbles = 0b00100101;
long bytes = 0b11010010011010011001010010010010;

 

Java7+

long creditCardNumber = 1234_5678_9012_3456L;
long socialSecurityNumber = 999_99_9999L;
byte nybbles = 0b0010_0101;
long bytes = 0b11010010_01101001_10010100_10010010;

Cannot put underscores:

  • adjacent to a decimal point
  • prior to an L suffix
  • at the end of a literal
  • some others

Multicatch exception

In Java SE 7 and later, a single catch block can handle more than one type of exception

Before Java7

  try {
      //...
  } catch (IOException ex) {
      logger.log(ex);
      throw ex;
  } catch (SQLException ex) {
      logger.log(ex);
      throw ex;
  }

 

Java7+

catch (IOException|SQLException ex) {
    logger.log(ex);
    throw ex;
}
 

NIO 2.0

Before Java7

  public void copyWithSameContents() throws IOException {
  
    File copied = new File("src/test/resources/copiedWithIo.txt");
    try (
      InputStream in = new BufferedInputStream(
        new FileInputStream(original));
      OutputStream out = new BufferedOutputStream(new FileOutputStream(copied))) {
  
        byte[] buffer = new byte[1024];
        int lengthRead;
        while ((lengthRead = in.read(buffer)) > 0) {
            out.write(buffer, 0, lengthRead);
            out.flush();
        }
    }
}

 

Java7+

public void copyWithSameContents() throws IOException {
  
    Path copied = Paths.get("src/test/resources/copiedWithNio.txt");
    Path originalPath = original.toPath();
    Files.copy(originalPath, copied, StandardCopyOption.REPLACE_EXISTING);
}
 

Using Java 8

  • Functional Programming + OOP
  • Two kinds of complexity
  • Power and perils of OOP and mutable state

 

  • What's wrong with mutable state of objects?
    • Error prone
    • Difficult to reason
    • Is not concurrency friendly

Using Java 8

  • forEach() method in Iterable
  • Default and static methods in Interfaces (Diamond problem)
  • Lambdas
  • Method references
  • Stream API
  • Higher-Order function
  • Java Time API
  • Nashorn Engine (will be deprecated in Java 11)
  • Repeating annotations
  • Optional

Default methods in Interfaces

  • Default methods in Interfaces

 

  • Static methods in Interfaces

 

  • Diamond problem

 

 

Code -> adefaultstaticmethods

Lambdas

Consumer<String> print = (String name) -> { System.out.println(name); };
Consumer<String> print = name -> System.out.println(name);
Consumer<String> print = System.out::println;
(String name) -> { System.out.println(name); };

Params

Arrow operator

Lambda body

How the inference happens? Code -> blambdafunctionalinterfaces

Lambdas

  • Functional Interfaces

    • Function

    • Predicate

    • Consumer

    • Supplier

    • BiFunction

    • UnaryOperator

    • ...

Code -> Example blambdafunctionalinterfaces

Method references

  • Is the shorthand syntax for a lambda expression that executes just ONE method

Code -> cmethodreference

Instead of using:

N ANONYMOUS CLASS
you can use:

 LAMBDA EXPRESSION
And if this just calls one method, you can use:

A METHOD REFERENCE

Method references

There are four types of method references:

  • To a static method.
  • To instance method of an object of a particular type.
  • To an instance method of an existing object.
  • To a constructor.

Stream API

  • Stream API

  • Less explicit assignments are needed.

  • Immutable state

  • Declarative code. Code -> ddeclarative

 

Code -> Example estreams

Higher-Order function

  • Higher-Order function

    • We can pass function to function

    • We can create function within function

    • We can return function from function

  • Pure functions = No side effects

 

Code -> Example fhigherorderpurefunctions

Java Time API

  • The old date library provided by JDK included only three classes:

    • java.util.Date

    • java.util.Calendar

    • java.util.Timezone

Using Java 8

The new Java Time API offers:

  • Clarity, Flexibility and Inmutability and thread safety:

    • Instant – a point in time (timestamp)

    • LocalDate – a date (year, month, day)

    • LocalDateTime – but includes time with nanosecond precision

    • ZonedDateTime – same as OffsetDateTime, but includes a time zone ID

  • Declarative API, method chaining:

ZonedDateTime nextFriday = LocalDateTime.now()
    .plusHours(1)
    .with(TemporalAdjusters.next(DayOfWeek.FRIDAY))
    .atZone(ZoneId.of("PST"));

Code -> gdatetime

What about Java 9?

  • JPMS

  • JShell

  • Javadoc search box

  • Collection factory methods

  • Optional to Stream

  • Private interface methods

  • HTTP/2, HTTP Client out of the box

  • Try-with-resources with final or effectively final variable

  • Reactive Streams

Collection factory methods

  • The collections created using factory methods are immutable and changing an element, adding new elements or removing an element throws UnsupportedOperationException

 

  • No null Element Allowed

 

  • Less verbosity

HttpClient out of the box

  •  It can be used to request HTTP resources over the network.

  • It supports HTTP/1.1 and HTTP/2, both synchronous and asynchronous programming models


  • Code -> AHttpClientTest

Java 10

 

  • Local-Variable Type Inference

  • Time-based Release Versioning

  •  Unmodifiable collection methods

  • Better Docker container integration

Local-Variable Type Inference

  • Its principal goal is to reduce boilerplate and enhance code readability.

  • We can replace the typein the local variable declaration with the keyword var

  • Each declaration has a static type
  • It only works in local variables,  not in fields or in method signatures
  • Variable name matter
  • It is limited compared to other languages

 

Code -> ALocalVariableTypeInference

Local-Variable Type Inference

  • Recommendations:

    • Prefer readability over reducing time to code

    • Use it if your team feels comfortable using it

    • Use it when both readability and maintenance of code benefits

Better container integration

  • The flags -XX:+UnlockExperimentalVMOptions and -XX:+UseCGroupMemoryLimitForHeap aren’t needed anymore for limit JVM memory inside a Docker container

         ​docker run -d ..... -m 600M

 

Java 11

         
           java SingleFileProgram.java

 

is equivalent to:

 

         javac SingleFileProgram.java
             java SingleFileProgram

 

Code -> SingleFileProgram

Summary

  • It's time to migrate at least to version 8 of Java

  • We can reduce accidental complexity by using  functional programming capabilities

  • Immutable state facilitates concurrent processing

  • Declarative code. Telling what to do, not how. 

  • It is important to keep up with the changes in the language

Ya es momento de migrar a Java 8+

By Augusto Alonso de la Cruz Jimenez

Ya es momento de migrar a Java 8+

  • 68