Beyond
Java 8
M. Dorra
July 17, 2020
How does Java
evolve?
● Java Community Process (JCP)
● Java/JDK Enhancement Proposal (JEP)
● Java Specification Request (JSR)
● JDK is a set of specifications, even JVM
● Many implementations
○ OracleJDK
○ OpenJDK
○ Corretto
○ Azul
○ Many other...
Specifications and Implementations
● More Agile
●
The new Release Cycle
The new Release Cycle
JEPs, JEPs… JEPs
● Modular System – Jigsaw Project
● JShell: the interactive Java REPL TryJShell
● Collection factory methods
● Interface Private Method
Java 9 features
Modular System – Jigsaw Project
● Better separation of concerns
● Stronger encapsulation to Java applications
● Package of Java Packages
module com.billing{
exports com.billing.iface;
}
module com.activity{
requires com.billing;
}
A Module is a group of closely related packages and resources along
with a new module descriptor file.
Collection factory methods
List<Integer> numbers = new ArrayList<>();
numbers.add(1);
numbers.add(2);
numbers.add(3);
Set<String> strings = new HashSet<>();
strings.add(“foo”);
strings.add(“bar”);
strings.add(“baz”);
Set<String> strings = Set.of("foo", "bar", "baz");
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> numbers = List.of(1, 2, 3, 4, 5);
Map<String, Integer> map = Map.of(
“ONE”, 1,
“TWO”, 2,
“THREE”, 3);
public interface Map<K,V>{
/**
* @since 9
*/
static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2){…}
static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3){…}
…
static <K, V> Map<K, V> of(K k1, V v1, … …, K k9, V v9){…}
Collection factory methods
Map<String, Integer> map = new TreeMap<>();
map.put(“ONE”, 1);
map.add(“TWO”, 2);
map.add(“THREE”, 3);
Interface Private Method
public interface BillingService{
default BillingBo calculate(BillingBo billing){
init(billing);
return doCalculate(billing);
}
BillingBo doCalculate(BillingBo billing);
private void init(BillingBo billing){
billing.setExportStatus(NOT_BILLED);
}
}
● Local-Variable Type Inference
● Collectors toUnmodifiable*()
● Optional*.orElseThrow()
● …
Java 10 features
● Limited only to Local Variable with initializer
● Indexes of enhanced for loop or indexes
● Local declared in for loop
● Not applicable to define a lambda
Local-Variable Type Inference
List<Integer> numbers = List.of(1, 2, 3, 4, 5); // Java 9
for (Integer number : numbers) {
System.out.println(number);
}
for (int i = 0; i < numbers.size(); i++) {
System.out.println(numbers.get(i));
}
● Limited only to Local Variable with initializer
● Indexes of enhanced for loop or indexes
● Local declared in for loop
Local-Variable Type Inference
var numbers = List.of(1, 2, 3, 4, 5);
for (var number : numbers) {
System.out.println(number);
}
for (var i = 0; i < numbers.size(); i++) {
System.out.println(numbers.get(i));
}
List<Map<String, String>> cabins = configManager.query(List.class, …)
var cabins = configManager.query(List.class, …)
Collectors toUnmodifiable*()
List<String> mutable = Stream.of("A").collect(Collectors.toList());
mutable.add(“B”);
List<String> immutable =
Stream.of("A").collect(Collectors.toUnmodifiableList());
immutable.add(“B”); // UnsupportedOperationException
Collectors.toUnmodifiableMap(…)
Collectors.toUnmodifiableSet()
Optional*.orElseThrow()
Optional<String> optional = Optional.ofNullable(null);
optional.get(); // NoSuchElementException
optional.orElseThrow();
//default of orElseThrow(Supplier<Exception> supplier)
● Makes more sense of usage
● New String methods
● Local-Variable Syntax for Lambda Parameters
● Implicitly compile and run
● …
Java 11 features
New String methods
org.apache.commons.lang.StringUtils.isEmpty()
org.apache.commons.lang.StringUtils.isBlank()
String myString = “Java 11”;
myString.isBlank();
myString = “Java 11n Java 12”;
myString.lines();
myString = “ Java 11 ”;
myString.strip();  trim()?  unicode
myString.stripLeading();
myString.stripHeading();
Local-Variable Syntax for Lambda
Parameters
var list = List.of(“A”, ”B”);
for(var item: list){…}
BiFunction<K, K, O> sum = (num1, num2) -> num1 + num2;
BiFunction<K, K, O> equals = (@Nonnull var obj1, var obj2) -> obj1 + obj2;
equals(null, new Object());
Some Rules for that:
(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.
Implicitly compile and run
public interface ByeWorld2020 {
public static void main(String … args){
System.out.println(“2020 O_o .. Bye, World!.”);
}
}
$> java ByWorld2020
$> javac ByWorld2020.java
Limited to single file classes :D
$> java ByWorld2020.java
$> 2020 O_o .. Bye, World!.
$>
● Switch Expressions (J12 preview, J14 feature)
● Pattern Matching for instanceof (J12 preview, J14 feature)
● Multi-line texts (J13 preview, J14 feature)
● Switch Expressions with yield
● Records (J14 preview)
● Helpful NullPointerException(s)
Java 12-14 features
Switch Expressions
enum Status {ON, OFF, UNKNOWN}
var status = Status.ON;
String result = “”;
switch(status){
case ON: result = “On”; break;
case OFF: result = “Off”; break;
case UNKNOWN: default: result = “Unknown”; break;
}
Statement vs Expression?
Switch Expressions
enum Status {ON, OFF, UNKNOWN}
var status = Status.ON;
String result = switch(status) {
case ON -> “On”;
case OFF -> “Off”;
case UNKNOWN, default -> “Unknown”;
}
Statement vs Expression?
Pattern Matching for instanceof
interface Flyable { void fly(); }
class Bird implements Flyable { public void fly(){…}
void birdEat();
}
class Eagle implements Flyable { public void fly(){…}
void eagleEat();
}
void runner(Flyable flyable) {
if(flyable instanceof Bird) {
Bird asBird = (Bird) flyable;
asBird.birdEat();
}
}
Pattern Matching for instanceof
interface Flyable { void fly(); }
class Bird implements Flyable { public void fly(){…}
void birdEat();
}
class Eagle implements Flyable { public void fly(){…}
void eagleEat();
}
void runner(Flyable flyable) {
if(flyable instanceof Bird asBird) {
Bird asBird = (Bird) flyable;
asBird.birdEat();
}
}
Pattern Matching for instanceof
interface Flyable { void fly(); }
class Bird implements Flyable { public void fly(){…}
void birdEat();
Boolean isX();
}
class Eagle implements Flyable { public void fly(){…}
void eagleEat();
}
void runner(Flyable flyable) {
if(flyable instanceof Bird asBird && asBird.isX()) {
Bird asBird = (Bird) flyable;
asBird.birdEat();
}
}
Pattern Matching for instanceof
interface Flyable { void fly(); }
class Bird implements Flyable { public void fly(){…}
void birdEat();
Boolean isX();
}
class Eagle implements Flyable { public void fly(){…}
void eagleEat();
}
void runner(Flyable flyable) {
if(flyable instanceof Bird asBird || asBird.isX()){
Bird asBird = (Bird) flyable;
asBird.birdEat();
}
}
Will not work
Pattern Matching for instanceof
trait Flyable
case class Bird (color: String) implements Flyable
case class Eagle implements Flyable
Flyable flyable = Bird(“<string>”)
val someVal = flyable match {
case Bird(“Red”) => …
case Bird(_) => …
case _ => …
}
Scala world
Multi-line texts
myStr = ‘’’
{“name”:”Groovy and Python”}
‘’’
val myStr = “””
{“name”:”Scala”}
“””
Already there in many languages
Multi-line texts
var query = “SELECT * FROM BILLINGS WHERE 1=1 “
+ ” AND OWNER = ‘MAG’ AND status = ‘BILLED’ ”
+ “ AND ACTION = ‘FLIGHT’”;
Already there in many languages
var query = “”” SELECT * FROM BILLINGS WHERE 1=1
AND OWNER = ‘MAG’ AND status = ‘BILLED’
AND ACTION = ‘FLIGHT’
“””;
Switch Expressions with yield
enum Status {ON, OFF, UNKNOWN}
var status = Status.ON;
String result = switch(status) {
case ON -> doSomeLogic();…; yield “On”;
case OFF -> doOtherLogic();…; yield “Off”;
case UNKNOWN -> doAnotherLogic();…; yield “Unknown”;
default -> out.println(“Why am I here?”); yield “Not Required”;
}
Records (data class)
class Bill {
many fields;
many getters;
many setters;
}
@lombok.Data
@lombok.Getter
@lombok.Setter
@lombok.ToString
@lombok. EqualsAndHashCode
class Bill {
many fields;
}
record Bill(fields) {
}
Helpful NullPointerException(s)
1. class NullPointerExample{
2. public static void main(String… args){
3. var b = new B();
4. String name = b.a.method();
5. }
6. }
class A {void method(){…}}
class B {A a;}
//Stacktrace
Exception in thread "main" java.lang.NullPointerException
at NullPointerExample.main(NullPointerExample.java:4)
//Stacktrace
Exception in thread "main" java.lang.NullPointerException 
Cannot invoke “A.method” because the return value of b.a is null
at NullPointerExample.main(NullPointerExample.java:4)
Many Other Enhancements
● Experimental Java-Based JIT Compiler (See
GraalVM)
● Enhanced GC: Parallel Full GC for G1
● HTTP Client with support for HTTP/2 and
websocket
● Reactive subscriber and publisher model (Flow)
● Remove the Java EE and CORBA Modules
● Deprecate the Nashorn JavaScript Engine
● … Tons of features
References
● JCP
● JEPs
● OpenJDK
● OpenJDK 14
● OpenJDK 15
Thank you