@MichelSchudel
michel@craftsmen.nl
@MichelSchudel
Java version usage as of october 2018
https://snyk.io/blog/jvm-ecosystem-report-2018/
@MichelSchudel
https://www.infoworld.com/article/3227244/java-9-is-here-everything-you-need-to-know.html
@MichelSchudel
• Solves the encapsulation gab at
module (JAR) level
• No access to internal non-cricital
API’s anymore
• Possibility of releasing small
programs (Jlink)
@MichelSchudel
module-info.java
module nl.craftsmen.myuimodule {
requires nl.craftsmen.myservicemodule;
exports nl.craftsmen.ui;
}
module nl.craftsmen.myservicemodule {
requires java.logging;
exports nl.craftsmen.service;
}
module
package
references
@MichelSchudel
Building a custom image
Jlink
--module-path target/classes
--add-modules moduledemo,java.base
--output moduledemo
--launcher
moduledemo=moduledemo/nl.craftsmen.moduledemo.ModuleDemo
@MichelSchudel
Hello, world! Image: 39MB
http://www.techort.com/review-of-java-9-habrahabr/
var text = "hi JBCNConf!";
var stringList = List.of("a", "b", "c");
var stringMap = Map.of("key1", "value1");
var intSet = Set.of(1,2,3);
var name = getName();
var otherThing = getNull();
String text = "hi JBCNConf!";
List<String> stringList = List.of("a", "b", "c");
Map<String,String> stringMap = Map.of("key1", "value1");
Set<Integer> intSet = Set.of(1,2,3);
String name = getName();
Object otherThing = getNull();
@MichelSchudel
//won't work, no type can be determined
var x;
//won't work, method reference
var name2 = Main::getName;
//won't work, null reference
var nullValue = null;
//won't work, array initializer
var stringArray = {1, 2};
@MichelSchudel
https://blog.overops.com/java-community-survey-results-74-of-developers-want-less-verbosity/
Local variable syntax for Lamba parameters
//java 10
(int x, int y) -> x + y;
//java 11
(var x, var y) -> x + y;
(x, y) -> x + y;
(@NotNull var x, @Nullable var y) -> x + y;
(var x, var y) -> x + y;
@MichelSchudel
Http Client
HttpClient client = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_1_1)
.followRedirects(HttpClient.Redirect.NORMAL)
.connectTimeout(Duration.ofSeconds(20))
.build();
HttpRequest httpRequest = HttpRequest
.newBuilder()
.header("myHeader", "myValue")
.uri(URI.create("http://localhost:4567/hello"))
.build();
HttpResponse<String> response = client
.send(httpRequest, HttpResponse.BodyHandlers.ofString());
@MichelSchudel
Some nice API additions
" ".isBlank()  true
 JBCNConfJBCNConf
Arrays.stream(someText.split("r")).forEach(System.out::println);
Optional<String> optional = getStringValue();
If (optional.isEmpty() {..}
someText.lines().forEach(System.out::println);
new String(new char[2])
.replace("0", “JBCNConf"));
“JBCNConf".repeat(2)
@MichelSchudel
https://docs.google.com/document/d/1nFGazvrCvHMZJgFstlbz
oHjpAVwv5DEdnaBr_5pKuHo/preview#heading=h.p3qt2oh5ec
zi
@MichelSchudel
You have to pay Oracle a periodic subscription fee if
• You use the OracleJDK commercially
• You‘re on java 9+ or want to use Java 8u211 or higher
Using the OracleJDK non-commercially is free
(at least until september 2020)
$2.5(USD) per month per user
$25(USD) per month per server
https://docs.google.com/document/d/1nFGazvrCvHMZJgFstlbz
oHjpAVwv5DEdnaBr_5pKuHo/preview#heading=h.p3qt2oh5ec
zi
@MichelSchudel
• Not free for commercial use since april 16th, 2019
• JDK8u211
• Older versions ARE free for commercial use
• AdoptOpenJDK (https://adoptopenjdk.net/)
• Amazon Corretto (https://aws.amazon.com/corretto/)
• Jclarity OpenJDK (https://www.jclarity.com/index.php)
If you want the latest security patches
• Get a subscription, or grab and openjdk build:
• OracleJDK not free for commercial use
• OpenJDK is free under GPLv2+CE license
• Only two quarterly updates, however
• AdoptOpenJDK (https://adoptopenjdk.net/)
• Amazon Corretto (https://aws.amazon.com/corretto/)
• Jclarity OpenJDK (https://www.jclarity.com/index.php)
• Get a subscription for the OracleJDK
• Get the Oracle OpenJDK (https://jdk.java.net/)
• For the latest security patches, grab an OpenJDK build:
https://blog.overops.com/the-complete-guide-to-java-12-new-features/
• JEP 325: Switch expressions
• Some small api changes
• JEP 326: Raw string literals
• JEP 189: Shenandoah GC
• JEP 341: Default CDS archives
• JEP 334: Constants API
• JEP 344: Abortable G1
@MichelSchudel
Switch expressions are experimental
To try out switch expressions, use
--enable-preview
parameterwhen starting JVM
https://github.com/MichelSchudel/java12demo
@MichelSchudel
• Ultra low-pause garbage collector
java -XX:+UseShenandoahGC
@since 13
@MichelSchudel
/**
* The singleton instance for the 'Reiwa' era (2019-05-01 - )
* which has the value 3. The end date of this era is not specified, unless
* the Japanese Government defines it.
*
* @since 13
*/
public static final JapaneseEra REIWA = new JapaneseEra(3, LocalDate.of(2019, 5, 1));
@MichelSchudel
Value Types (JEP-169)
class Tuple {
int val1;
int val2;
}
Object
header
val1
val2
Object
header
val1
val2
Object
header
val1
val2
value class Tuple
{
int value1;
int value2;
}
val1, val2
val1, val2
val1, val2
@MichelSchudel
Cl
Value Types (JEP-169)
• No object identity (does NOT extend Object)
• Instances are equal based on their data
• Immutable (just like primitives)
“Codes like a class, works like an int” – Brian Goetz
…but what about generics?
@MichelSchudel
With introducing value types, restriction on
Object when using generics becomes more
cumbersome
List<int> integers;
List<Tuple> tuples;
Generic specialization (JEP-218)
@MichelSchudel
Current threading model
Runnable
Runnable
Executor
Thread
Thread
Thread
Thread
Current threading model
Thread
Task Scheduler
Instructions Switch thread
OS OS
Current threading model
• Thread call stack includes native stack (big
footprint)
• No way to guarantee that two related
threads run on the same cpu (core)
@MichelSchudel
Solution
Core Core
Core Core
Fibers
Threads
Java Fiber Scheduler
OS Thread Scheduler
(fe ForkJoinPool)
@MichelSchudel
Delivered
• Local-variable type inference (JEP-286), JDK10
• Local-variable syntax for lambda parameters (JEP-323), JDK11
Preview
• Switch expressions (JEP-325) (JDK12)
In development
• Raw string literals (JEP-326) Text blocks (JEP-355)
• Pattern matching (JEP-310)
On hold
• Enhanced enums (JEP-301)
@MichelSchudel
Text blocks (JEP-355)
String html = "<html>n" +
" <body>n" +
" <p>Hello, "world"</p>n" +
" </body>n“ +
"</html>n";
String html = """
<html>
<body>
<p>Hello, "world"</p>
</body>
</html>
""";
..............
..............
..............
..............
..............
..............
@MichelSchudel
Pattern matching (JEP-355)
Object obj =…
if (obj instanceof String) {
String s = (String)obj;
System.out.println(s.toUpperCase());
} else if (obj instanceof Integer) {
Integer i = (Integer)obj;
System.out.println(i.doubleValue());
}
Object obj =…
if (obj instanceof String s) {
System.out.println(s.toUpperCase());
} else if (obj instanceof Integer i) {
System.out.println(i.doubleValue());
}
@MichelSchudel
Pattern matching (JEP-355)
String formatted = switch (obj) {
case Integer i -> String.format("int %d", i);
case Byte b -> String.format("byte %d", b);
case Long l -> String.format("long %d", l);
case Double d -> String.format("double %f", d);
case String s -> String.format("String %s, s);
default -> String.format("Object %s", obj);
};
@MichelSchudel
interface Expression{
int evaluate();
}
class SimpleExpression implements Expression {
int value;
int evaluate() {
return value;
}
}
class ComplexExpression implements Expression {
Expression left, right;
int evaluate() {
return left.evaluate() + right.evaluate();
}
}
Pattern matching (JEP-355)
@MichelSchudel
interface ExpressionVisitor<T> {
T visit(SimpleExpression expression);
T visit(ComplexExpression expression);
}
Pattern matching (JEP-355)
class MyVisitor implements ExpressionVisitor<Integer> {
Integer visit(SimpleExpression expr) { return expr.value; }
Integer visit(ComplexExpression expr) { return expr.left.accept(this)
+ expr.right.accept(this); }
}
@MichelSchudel
int evaluate(Expression expr) {
return switch(expr) {
case SimpleExpression(int value) -> value;
case ComplexExpression(Expression left, Expression right) ->
evaluate(left) + evaluate(right);
};
}
Pattern matching (JEP-355)
Deconstruction patterns
class SimpleExpression { value }
class ComplexExpression { left, right }
value
value
@MichelSchudel
https://openjdk.java.net/projects/panama/
https://openjdk.java.net/projects/valhalla/
https://openjdk.java.net/projects/amber/
https://openjdk.java.net/projects/loom/
• Java 9, 10, 11 recap
• Java 12 overview
• Java 13 preview
• The Java future
• Panama
• Valhalla
• Loom
• Amber
Uncovering project Amber
Mala Gupta
Java Futures
Brian Goetz
OpenJDK, the Future of Java
Mario Torre
How to participate in the future of Java
Heather VanCura
https://github.com/MichelSchudel/java12demo
@MichelSchudel
michel@craftsmen.nl
Demo slides
(in case you didn’t see the demo
about what’s new in java 12
Traditional switch statement
public String getConference(Conference conference) {
switch (conference) {
case JBCNCONF:
return "JBCNConf";
case DEVOXX:
return "Devoxx";
case DEVOXX_UK:
return "Devoxx UK";
default:
throw new RuntimeException("unknown type!");
}
}
A traditional switch statement. Notice that the default must be specified,
Even although the enum’s values are exhausted
Switch expression
public String getConferenceExpression(Conference conference) {
String s = switch (conference) {
case JBCNCONF:
break "JBCNConf";
case DEVOXX:
break "Devoxx";
case DEVOXX_UK:
break "DevoxxUK";
};
return s;
}
A switch expression. The break returns the value. Since it’s an expression,
You dont need a default statement since all enum values are convered.
Switch expression, lamba style
public String getConferenceLambdas(Conference conference) {
String s = switch (conference) {
case JBCNCONF -> "JBCNConf";
case DEVOXX -> "Devoxx";
case DEVOXX_UK -> "DevoxxUK";
};
return s;
}
Switch expressions can be elegantly written lamba style.
Multilabel switch expressions
public String getConferenceMultiLabel(Conference conference) {
String s = switch (conference) {
case JBCNCONF -> "JBCNConf";
case DEVOXX, DEVOXX_UK -> "Devoxx";
};
return s;
}
You can state multiple labels for one branch, without the nasty fallthrough cases without breaks.
public String getConferenceMultiStatement(Conference conference) {
String s = switch (conference) {
case JBCNCONF -> {
System.out.println("conference = [" + conference + "]");
break "JBCNConf";
}
case DEVOXX, DEVOXX_UK -> "Devoxx";
};
return s;
}
Switch expression, multiline
Multiple expressions are delimited by {}. In this case, you MUST use a break.
Switch expression, supertype
public Object getConferenceTypeResolving(Conference conference) {
Object s = switch (conference) {
case JBCNCONF -> {
System.out.println("conference = [" + conference + "]");
break "JBCNConf";
}
case DEVOXX, DEVOXX_UK -> "Devoxx";
default -> new RuntimeException();
};
return s;
}
When multiple branches return multiple types, the type of the switch expression is the closest
common supertype.
Teeing collector
The teeing collector takes two Collectors, and passes both Collector results to a function.
public void teeingDemo() {
double average = Stream.of(1, 4, 2, 7, 4, 12)
.collect(Collectors.teeing(
Collectors.summingDouble(i -> i),
Collectors.counting(),
(sum, n) -> sum / n));
System.out.println(average);
}
String transform method
The new transform method takes a function to transform a string. The output can be any type.
public void transformDemo() {
String conference = "2019";
Integer i = conference.transform(Integer::parseInt);
System.out.println(i);
}