KEMBAR78
Amber and beyond: Java language changes | PDF
Amber and Beyond
Where is Java headed?
Stephen Colebourne - @jodastephen
Engineering Lead, OpenGamma
May 2018
Topics
● Introduction
● Local variable type inference
● Raw string literals
● Expression switch
● Pattern matching
● Records
● Value types
● Summary
Introduction
https://www.flickr.com/photos/jodastephen/25361375631/
Introduction
● Java continues to develop
● 3½ years from Java 8 to Java 9
● Too slow!
● New plan is to release Java every six months
Releases
● Release every six months
Java 8 March 2014
Java 9 September 2017
Java 10 March 2018
Java 11 September 2018
Java 12 March 2019
...
Releases
● Some releases are LTS (Long Term Support)
Java 8 March 2014 Long term support
Java 9 September 2017 Obsolete
Java 10 March 2018 Five months until obsolete
Java 11 September 2018 Long term support
Java 12 March 2019 Obsolete when Java 13 released
...
Releases
● Other releases are quickly obsolete
Java 8 March 2014 Long term support
Java 9 September 2017 Obsolete
Java 10 March 2018 Five months until obsolete
Java 11 September 2018 Long term support
Java 12 March 2019 Obsolete when Java 13 released
...
Releases
● Companies focus on LTS releases
● Other releases are fully stable...
● ...but you need to move off them quickly
● Maximum 1 month to move to next release
Language changes
● Language changes now more frequent
● New feature every six months is possible
● Need to provide feedback to Oracle quickly
● (I don't work at Oracle!)
Local Variable Type Inference
https://www.flickr.com/photos/jodastephen/22471104851/
Local Variable Type Inference
● JEP 286 - http://openjdk.java.net/jeps/286
● Released in Java 10
"Enhance the Java Language to extend type inference to
declarations of local variables with initializers."
Local Variable Type Inference
● New keyword var
Path path = Paths.get("/src/main/java/module-info.java");
List<String> lines = Files.readAllLines(path);
Local Variable Type Inference
● New keyword var
Path path = Paths.get("/src/main/java/module-info.java");
List<String> lines = Files.readAllLines(path);
Local Variable Type Inference
● New keyword var
var path = Paths.get("/src/main/java/module-info.java");
var lines = Files.readAllLines(path);
Local Variable Type Inference
● New keyword var
var path = Paths.get("/src/main/java/module-info.java");
var lines = Files.readAllLines(path);
Local Variable Type Inference
● New keyword var
var path = Paths.get("/src/main/java/module-info.java");
var lines = Files.readAllLines(path);
Still has type List<String>
Local Variable Type inference
● Local variables only
○ cannot change method signatures
○ cannot change fields
● Variable still has a type
○ not like JavaScript
Local Variable Type Inference
● Can be used in loops
var path = Paths.get("/src/main/java/module-info.java");
var lines = Files.readAllLines(path);
for (var line : lines) {
// happy days!
}
● There is no val
○ it wouldn't have worked well in Java
● Choose one inference for generics:
○ List<String> lines = new ArrayList<>();
○ var lines = new ArrayList<String>();
● See the style guide for tips on usage
○ http://openjdk.java.net/projects/amber/LVTIstyle.html
Local Variable Type inference
Raw string literals
https://www.flickr.com/photos/jodastephen/22419484102/
Raw String Literals
● JEP 326 - http://openjdk.java.net/jeps/326
● Under discussion, probably in Java 11
"Add raw string literals to the Java programming language.
A raw string literal can span multiple lines of source code
and does not interpret escape sequences."
Raw string literals
● Use backtick as a delimiter
● Content retained as is, no escaping
var path = Paths.get("C:Program Filesfoo");
var path = Paths.get(`C:Program Filesfoo`);
Raw string literals
● Regular expressions benefit greatly
● Still just a java.lang.String
var regex = Pattern.compile("(Hello (w))]");
var regex = Pattern.compile(`(Hello (w))]`);
Raw string literals
● Can contain new lines
● Embed backticks with a different length delimiter
var markdown = ````The calculator is very useful:
```
var pi = magicCalculator(3, 4);
```
This code will calculate PI.
````;
Raw string literals
● Can contain new lines
● Embed backticks with a different length delimiter
var markdown = ````The calculator is very useful:
```
var pi = magicCalculator(3, 4);
```
This code will calculate PI.
````;
Raw string literals
● Open question around stripping indents
var html = `
<html>
<body>
<p>Hello World</p>
</body>
</html>
`;
Raw string literals
● Open question around stripping indents
var html = `
<html>
<body>
<p>Hello World</p>
</body>
</html>
`;
Raw string literals
public void execute() {
output(`C:apps`, ``);
var dir = `C:dev`;
output(dir, ``);
}
public void output(String str, String suffix) {
System.out.println(str + suffix);
}
Raw string literals
public void execute() {
output(`C:apps`, ``);
var dir = `C:dev`;
output(dir, ``);
}
public void output(String str, String suffix) {
System.out.println(str + suffix);
}
What does this code do?
a) Prints:
C:apps
C:dev
b) Compile error
c) Print something else
d) Runtime exception
Raw string literals
public void execute() {
output(`C:apps`, ``);
var dir = `C:dev`;
output(dir, ``);
}
public void output(String str, String suffix) {
System.out.println(str + suffix);
}
Raw string literals
public void execute() {
output(`C:apps`, ``);
var dir = `C:dev`;
output(dir, ``);
}
public void output(String str, String suffix) {
System.out.println(str + suffix);
}
Raw string literals
public void execute() {
output(`C:apps`, ``);
var dir = `C:dev`;
output(dir, ``);
}
public void output(String str, String suffix) {
System.out.println(str + suffix);
}
c) Print something else:
C:apps);
var dir = `C:dev`;
output(dir,
Raw string literals - my views
● Raw string literals will be useful
○ particularly for regular expressions
● I'd prefer a different design
○ separate single-line and multi-line literals
○ allow empty literals
Expression switch
https://www.flickr.com/photos/jodastephen/22250774560/
Expression switch
● JEP 325 - http://openjdk.java.net/jeps/325
● Under discussion
"Extend the switch statement so that it can be used as
either a statement or an expression,
and improve how switch handles nulls."
Expression switch
● Switch today is a statement
String lightName;
switch (trafficLight) {
case RED: lightName = "Red";
case YELLOW: lightName = "Yellow";
case GREEN: lightName = "Green";
}
System.out.println(lightName);
Expression switch
● Oops, everything was green!
String lightName;
switch (trafficLight) {
case RED: lightName = "Red"; break;
case YELLOW: lightName = "Yellow"; break;
case GREEN: lightName = "Green"; break;
}
System.out.println(lightName);
Expression switch
● Oops, we forgot the impossible default!
String lightName;
switch (trafficLight) {
case RED: lightName = "Red"; break;
case YELLOW: lightName = "Yellow"; break;
case GREEN: lightName = "Green"; break;
default: throw new AssertionError("Bad enum");
}
System.out.println(lightName);
Expression switch
● Switch statement is error prone
● I prefer uses where each branch calls return
○ then the compiler traps some bugs
● Language design choice:
○ extend switch, but pick up flaws
○ create something like switch but new, say "matches", avoid flaws
Switch x 4
● Current plan is 3 new types of switch
○ Classic statement
○ Classic expression (new)
○ Enhanced statement (new)
○ Enhanced expression (new)
● Forms a 2x2 grid
○ Statement vs Expression
○ Classic (fall through) vs Enhanced (no fall through)
● 95%+ uses likely to be Enhanced, not Classic
Break expression
● New type of break
○ the break keyword followed by an expression
● Syntax clashes with labelled break
○ hopefully not a major problem in most codebases
Classic Expression switch
● Every route through switch must provide a result
var lightName = switch (trafficLight) {
case RED: break "Red";
case YELLOW: break "Yellow";
case GREEN: break "Green";
}
Classic Expression switch
● Classic still has fall through
var lightName = switch (trafficLight) {
case RED: break "Red";
case YELLOW: System.out.println(); // fall through!
case GREEN: break "Green";
}
Enhanced Expression switch
● Enhanced form has arrow instead of colon
var lightName = switch (trafficLight) {
case RED -> "Red";
case YELLOW -> "Yellow";
case GREEN -> "Green";
}
Enhanced Expression switch
● Arrow implies/requires break, no fall through
var lightName = switch (trafficLight) {
case RED -> "Red";
case YELLOW -> {
System.out.println();
break "Yellow"; // break required, no fall through
}
case GREEN -> "Green";
}
Enhanced Statement switch
● No need for break, no fall through
String lightName = null;
switch (trafficLight) {
case RED -> lightName = "Red";
case YELLOW -> lightName = "Yellow";
case GREEN -> lightName = "Green";
}
Expression switch rules
● Potentially no need for default clause with enums
○ one that throws an exception added for you
● Blocks will be allowed but with restrictions
○ won't allow return keyword
○ won't allow continue keyword
○ won't allow other types of break
Expression switch
● Comma separate shared cases
var action = switch (trafficLight) {
case RED, YELLOW -> "Stop";
case GREEN -> "Go";
}
Expression switch
● May be able to handle null
var action = switch (trafficLight) {
case null -> "Panic!!!";
case RED -> "Stop";
case YELLOW -> "SlowAndStop";
case GREEN -> "Go";
}
What does this do?
● Puzzler
var action = switch (trafficLight) {
case RED -> YELLOW -> stop(junction);
case GREEN -> car -> go(junction);
}
Alternatives
var option1 = switch (trafficLight) {
case RED -> car -> stop(car, junction);
}
var option2 = switch (trafficLight) {
case RED:= car -> stop(car, junction);
}
var option3 = match (trafficLight) {
case RED: car -> stop(car, junction);
}
Expression switch - my views
● Most switch statements could be expressions
● Fall through is very, very rare
● I find the current proposal overly complex
○ if..else statement -> ternary expression
○ switch statement -> switch expression ???
○ arrow operator has different meaning to use with lambdas
○ three new types of switch seems like overkill
Pattern matching
https://www.flickr.com/photos/jodastephen/40771473472/
Pattern matching
● JEP 305 - http://openjdk.java.net/jeps/305
● Future direction
"Enhance the Java programming language with pattern
matching. Initial support will include type-test and constant
patterns, supported by … a matches expression."
Pattern matching
● This code is boring and error-prone
String result = "unknown";
if (obj instanceof Integer) {
result = calculateInt(((Integer) obj).intValue());
} else if (obj instanceof Long) {
result = calculateLong(((Long) obj).longValue());
}
System.out.println(result);
Pattern matching
● Check the type
String result = "unknown";
if (obj instanceof Integer) {
result = calculateInt(((Integer) obj).intValue());
} else if (obj instanceof Long) {
result = calculateLong(((Long) obj).longValue());
}
System.out.println(result);
Pattern matching
● Convert to the checked type
String result = "unknown";
if (obj instanceof Integer) {
result = calculateInt(((Integer) obj).intValue());
} else if (obj instanceof Long) {
result = calculateLong(((Long) obj).longValue());
}
System.out.println(result);
Pattern matching
● Get the part we want
String result = "unknown";
if (obj instanceof Integer) {
result = calculateInt(((Integer) obj).intValue());
} else if (obj instanceof Long) {
result = calculateLong(((Long) obj).longValue());
}
System.out.println(result);
Pattern matching
● Use "matches" to check and convert
String result = "unknown";
if (obj matches Integer ival) {
result = calculateInt(ival);
} else if (obj matches Long lval) {
result = calculateLong(lval);
}
System.out.println(result);
Pattern matching
● Combines with expression switch
String result = switch (obj) {
case Integer ival -> calculateInt(ival);
case Long lval -> calculateLong(lval);
default -> "unknown";
}
System.out.println(result);
Pattern matching
● Better solution to nasty if..else chains
● Fairly obvious to understand
● Plan is for more complex patterns over time
Pattern matching
● Patterns executed in order, unlike current switch
String result = switch (obj) {
case String str && !str.isEmpty() -> calculateStr(str);
case String str -> "empty string";
default "unknown";
}
System.out.println(result);
Pattern matching - my views
● All looks good so far
● Issues mostly tied up in expression switch
Records
https://www.flickr.com/photos/jodastephen/39703321945/
Records
● No language level access to "properties" in "bean"
● This limits pattern matching
● Concept to add "records" to solve this
Records
● Short syntax
● Generated getters
● Generated equals/hashCode/toString
● Generated constructor
● Generated deconstructor
Records
● http://cr.openjdk.java.net/~briangoetz/amber/datum.html
"The API for a data class models the state,
the whole state, and nothing but the state."
Records
● Minimal syntax, maximum sugar
record Person(String forename, String surname) {};
// creates fields
// creates getters - forename(), surname()
// creates equals/hashCode/toString
// creates constructor/deconstructor
Records
● Plain carriers for data
○ the API of the class is fully coupled to the data
● No additional fields
● Can freely explode a record
○ Record <-> HashMap-like representation
○ constructor and deconstuctor
○ thus state cannot be hidden
Records
● Quick to define simple data
interface Shape { }
record Point(int x, int y);
record Rect(Point p1, Point p2) implements Shape;
record Circle(Point center, int radius) implements Shape;
Records
● Fits into pattern matching
switch (shape) {
case Rect(Point(var x1, var y1), Point(var x2, var y2)):…
case Circle(Point(var x, var y), var r): …
…
}
Records
● Can add user-defined methods
● Cannot replace equals/hashCode
● Can add additional constructors
● Cannot extend arbitrary class
● Can have static methods and fields
● Arrays are not well handled, use lists
● May be mutable, but may favour immutability
Records - my views
● Should be great, I still have some concerns
● Need to ensure support enough use cases
● Potential big cliff edge back to existing classes
● Class header syntax doesn't scale attractively
● Needs an abstraction across records and beans
Value types
https://www.flickr.com/photos/jodastephen/39988344374/
Value types
● JEP 169 - http://openjdk.java.net/jeps/169
● Future direction
"Provide JVM infrastructure for working with immutable and
reference-free objects, in support of efficient by-value
computation with non-primitive types."
Value types
● Reference types have identity
○ two String instances may be .equal() but not ==
● Primitive types do not have identity
○ int 6 is always int 6
● Value types are user-written code without identity
Value types
● Consider two LocalDate objects
LocalDate date1 = LocalDate.of(2018, 4, 1);
LocalDate date2 = LocalDate.of(2018, 4, 1);
date1.equals(date2); // true
date1 == date2; // false
// this distinction is not helpful
Value types
● Really, LocalDate should be a value type
● No actual requirement for identity
● Only need one "1st April 2018"
Value types
● No firm syntax exists yet
value Point(int x, int y);
value Rect(Point p1, Point p2);
Value types
Rect memory:
Header
p1: reference pointer
p2: reference pointer
Point memory:
Header
x: int
y: int
Point memory:
Header
x: int
y: int
As objects today:
Value types
Rect memory:
Header
p1.x : int
p1.y : int
p2.x : int
p2.y : int
As values:
Value types
● No identity, no ==
● No synchronization
● Ability to optimize memory layout
○ potential performance boost
● Will need generics over value types
○ this is pretty complex in its own right
Value types - my view
● Long term effort
● Good to see progress
● Direction improving over time
Summary
https://www.flickr.com/photos/jodastephen/25815472947/
Summary
● Lots of language change on the way
● Give feedback if you can
○ particularly if you can actually provide data points
● Interesting times!
Summary
● Project Amber:
○ http://openjdk.java.net/projects/amber/
○ Keep on giving feedback
● Stephen Colebourne:
○ @jodastephen - feedback & questions
○ http://blog.joda.org
● OpenGamma
○ Strata - open source market risk analytics
○ Cloud-hosted analytics for the derivatives market

Amber and beyond: Java language changes

  • 1.
    Amber and Beyond Whereis Java headed? Stephen Colebourne - @jodastephen Engineering Lead, OpenGamma May 2018
  • 2.
    Topics ● Introduction ● Localvariable type inference ● Raw string literals ● Expression switch ● Pattern matching ● Records ● Value types ● Summary
  • 3.
  • 4.
    Introduction ● Java continuesto develop ● 3½ years from Java 8 to Java 9 ● Too slow! ● New plan is to release Java every six months
  • 5.
    Releases ● Release everysix months Java 8 March 2014 Java 9 September 2017 Java 10 March 2018 Java 11 September 2018 Java 12 March 2019 ...
  • 6.
    Releases ● Some releasesare LTS (Long Term Support) Java 8 March 2014 Long term support Java 9 September 2017 Obsolete Java 10 March 2018 Five months until obsolete Java 11 September 2018 Long term support Java 12 March 2019 Obsolete when Java 13 released ...
  • 7.
    Releases ● Other releasesare quickly obsolete Java 8 March 2014 Long term support Java 9 September 2017 Obsolete Java 10 March 2018 Five months until obsolete Java 11 September 2018 Long term support Java 12 March 2019 Obsolete when Java 13 released ...
  • 8.
    Releases ● Companies focuson LTS releases ● Other releases are fully stable... ● ...but you need to move off them quickly ● Maximum 1 month to move to next release
  • 9.
    Language changes ● Languagechanges now more frequent ● New feature every six months is possible ● Need to provide feedback to Oracle quickly ● (I don't work at Oracle!)
  • 10.
    Local Variable TypeInference https://www.flickr.com/photos/jodastephen/22471104851/
  • 11.
    Local Variable TypeInference ● JEP 286 - http://openjdk.java.net/jeps/286 ● Released in Java 10 "Enhance the Java Language to extend type inference to declarations of local variables with initializers."
  • 12.
    Local Variable TypeInference ● New keyword var Path path = Paths.get("/src/main/java/module-info.java"); List<String> lines = Files.readAllLines(path);
  • 13.
    Local Variable TypeInference ● New keyword var Path path = Paths.get("/src/main/java/module-info.java"); List<String> lines = Files.readAllLines(path);
  • 14.
    Local Variable TypeInference ● New keyword var var path = Paths.get("/src/main/java/module-info.java"); var lines = Files.readAllLines(path);
  • 15.
    Local Variable TypeInference ● New keyword var var path = Paths.get("/src/main/java/module-info.java"); var lines = Files.readAllLines(path);
  • 16.
    Local Variable TypeInference ● New keyword var var path = Paths.get("/src/main/java/module-info.java"); var lines = Files.readAllLines(path); Still has type List<String>
  • 17.
    Local Variable Typeinference ● Local variables only ○ cannot change method signatures ○ cannot change fields ● Variable still has a type ○ not like JavaScript
  • 18.
    Local Variable TypeInference ● Can be used in loops var path = Paths.get("/src/main/java/module-info.java"); var lines = Files.readAllLines(path); for (var line : lines) { // happy days! }
  • 19.
    ● There isno val ○ it wouldn't have worked well in Java ● Choose one inference for generics: ○ List<String> lines = new ArrayList<>(); ○ var lines = new ArrayList<String>(); ● See the style guide for tips on usage ○ http://openjdk.java.net/projects/amber/LVTIstyle.html Local Variable Type inference
  • 20.
  • 21.
    Raw String Literals ●JEP 326 - http://openjdk.java.net/jeps/326 ● Under discussion, probably in Java 11 "Add raw string literals to the Java programming language. A raw string literal can span multiple lines of source code and does not interpret escape sequences."
  • 22.
    Raw string literals ●Use backtick as a delimiter ● Content retained as is, no escaping var path = Paths.get("C:Program Filesfoo"); var path = Paths.get(`C:Program Filesfoo`);
  • 23.
    Raw string literals ●Regular expressions benefit greatly ● Still just a java.lang.String var regex = Pattern.compile("(Hello (w))]"); var regex = Pattern.compile(`(Hello (w))]`);
  • 24.
    Raw string literals ●Can contain new lines ● Embed backticks with a different length delimiter var markdown = ````The calculator is very useful: ``` var pi = magicCalculator(3, 4); ``` This code will calculate PI. ````;
  • 25.
    Raw string literals ●Can contain new lines ● Embed backticks with a different length delimiter var markdown = ````The calculator is very useful: ``` var pi = magicCalculator(3, 4); ``` This code will calculate PI. ````;
  • 26.
    Raw string literals ●Open question around stripping indents var html = ` <html> <body> <p>Hello World</p> </body> </html> `;
  • 27.
    Raw string literals ●Open question around stripping indents var html = ` <html> <body> <p>Hello World</p> </body> </html> `;
  • 28.
    Raw string literals publicvoid execute() { output(`C:apps`, ``); var dir = `C:dev`; output(dir, ``); } public void output(String str, String suffix) { System.out.println(str + suffix); }
  • 29.
    Raw string literals publicvoid execute() { output(`C:apps`, ``); var dir = `C:dev`; output(dir, ``); } public void output(String str, String suffix) { System.out.println(str + suffix); } What does this code do? a) Prints: C:apps C:dev b) Compile error c) Print something else d) Runtime exception
  • 30.
    Raw string literals publicvoid execute() { output(`C:apps`, ``); var dir = `C:dev`; output(dir, ``); } public void output(String str, String suffix) { System.out.println(str + suffix); }
  • 31.
    Raw string literals publicvoid execute() { output(`C:apps`, ``); var dir = `C:dev`; output(dir, ``); } public void output(String str, String suffix) { System.out.println(str + suffix); }
  • 32.
    Raw string literals publicvoid execute() { output(`C:apps`, ``); var dir = `C:dev`; output(dir, ``); } public void output(String str, String suffix) { System.out.println(str + suffix); } c) Print something else: C:apps); var dir = `C:dev`; output(dir,
  • 33.
    Raw string literals- my views ● Raw string literals will be useful ○ particularly for regular expressions ● I'd prefer a different design ○ separate single-line and multi-line literals ○ allow empty literals
  • 34.
  • 35.
    Expression switch ● JEP325 - http://openjdk.java.net/jeps/325 ● Under discussion "Extend the switch statement so that it can be used as either a statement or an expression, and improve how switch handles nulls."
  • 36.
    Expression switch ● Switchtoday is a statement String lightName; switch (trafficLight) { case RED: lightName = "Red"; case YELLOW: lightName = "Yellow"; case GREEN: lightName = "Green"; } System.out.println(lightName);
  • 37.
    Expression switch ● Oops,everything was green! String lightName; switch (trafficLight) { case RED: lightName = "Red"; break; case YELLOW: lightName = "Yellow"; break; case GREEN: lightName = "Green"; break; } System.out.println(lightName);
  • 38.
    Expression switch ● Oops,we forgot the impossible default! String lightName; switch (trafficLight) { case RED: lightName = "Red"; break; case YELLOW: lightName = "Yellow"; break; case GREEN: lightName = "Green"; break; default: throw new AssertionError("Bad enum"); } System.out.println(lightName);
  • 39.
    Expression switch ● Switchstatement is error prone ● I prefer uses where each branch calls return ○ then the compiler traps some bugs ● Language design choice: ○ extend switch, but pick up flaws ○ create something like switch but new, say "matches", avoid flaws
  • 40.
    Switch x 4 ●Current plan is 3 new types of switch ○ Classic statement ○ Classic expression (new) ○ Enhanced statement (new) ○ Enhanced expression (new) ● Forms a 2x2 grid ○ Statement vs Expression ○ Classic (fall through) vs Enhanced (no fall through) ● 95%+ uses likely to be Enhanced, not Classic
  • 41.
    Break expression ● Newtype of break ○ the break keyword followed by an expression ● Syntax clashes with labelled break ○ hopefully not a major problem in most codebases
  • 42.
    Classic Expression switch ●Every route through switch must provide a result var lightName = switch (trafficLight) { case RED: break "Red"; case YELLOW: break "Yellow"; case GREEN: break "Green"; }
  • 43.
    Classic Expression switch ●Classic still has fall through var lightName = switch (trafficLight) { case RED: break "Red"; case YELLOW: System.out.println(); // fall through! case GREEN: break "Green"; }
  • 44.
    Enhanced Expression switch ●Enhanced form has arrow instead of colon var lightName = switch (trafficLight) { case RED -> "Red"; case YELLOW -> "Yellow"; case GREEN -> "Green"; }
  • 45.
    Enhanced Expression switch ●Arrow implies/requires break, no fall through var lightName = switch (trafficLight) { case RED -> "Red"; case YELLOW -> { System.out.println(); break "Yellow"; // break required, no fall through } case GREEN -> "Green"; }
  • 46.
    Enhanced Statement switch ●No need for break, no fall through String lightName = null; switch (trafficLight) { case RED -> lightName = "Red"; case YELLOW -> lightName = "Yellow"; case GREEN -> lightName = "Green"; }
  • 47.
    Expression switch rules ●Potentially no need for default clause with enums ○ one that throws an exception added for you ● Blocks will be allowed but with restrictions ○ won't allow return keyword ○ won't allow continue keyword ○ won't allow other types of break
  • 48.
    Expression switch ● Commaseparate shared cases var action = switch (trafficLight) { case RED, YELLOW -> "Stop"; case GREEN -> "Go"; }
  • 49.
    Expression switch ● Maybe able to handle null var action = switch (trafficLight) { case null -> "Panic!!!"; case RED -> "Stop"; case YELLOW -> "SlowAndStop"; case GREEN -> "Go"; }
  • 50.
    What does thisdo? ● Puzzler var action = switch (trafficLight) { case RED -> YELLOW -> stop(junction); case GREEN -> car -> go(junction); }
  • 51.
    Alternatives var option1 =switch (trafficLight) { case RED -> car -> stop(car, junction); } var option2 = switch (trafficLight) { case RED:= car -> stop(car, junction); } var option3 = match (trafficLight) { case RED: car -> stop(car, junction); }
  • 52.
    Expression switch -my views ● Most switch statements could be expressions ● Fall through is very, very rare ● I find the current proposal overly complex ○ if..else statement -> ternary expression ○ switch statement -> switch expression ??? ○ arrow operator has different meaning to use with lambdas ○ three new types of switch seems like overkill
  • 53.
  • 54.
    Pattern matching ● JEP305 - http://openjdk.java.net/jeps/305 ● Future direction "Enhance the Java programming language with pattern matching. Initial support will include type-test and constant patterns, supported by … a matches expression."
  • 55.
    Pattern matching ● Thiscode is boring and error-prone String result = "unknown"; if (obj instanceof Integer) { result = calculateInt(((Integer) obj).intValue()); } else if (obj instanceof Long) { result = calculateLong(((Long) obj).longValue()); } System.out.println(result);
  • 56.
    Pattern matching ● Checkthe type String result = "unknown"; if (obj instanceof Integer) { result = calculateInt(((Integer) obj).intValue()); } else if (obj instanceof Long) { result = calculateLong(((Long) obj).longValue()); } System.out.println(result);
  • 57.
    Pattern matching ● Convertto the checked type String result = "unknown"; if (obj instanceof Integer) { result = calculateInt(((Integer) obj).intValue()); } else if (obj instanceof Long) { result = calculateLong(((Long) obj).longValue()); } System.out.println(result);
  • 58.
    Pattern matching ● Getthe part we want String result = "unknown"; if (obj instanceof Integer) { result = calculateInt(((Integer) obj).intValue()); } else if (obj instanceof Long) { result = calculateLong(((Long) obj).longValue()); } System.out.println(result);
  • 59.
    Pattern matching ● Use"matches" to check and convert String result = "unknown"; if (obj matches Integer ival) { result = calculateInt(ival); } else if (obj matches Long lval) { result = calculateLong(lval); } System.out.println(result);
  • 60.
    Pattern matching ● Combineswith expression switch String result = switch (obj) { case Integer ival -> calculateInt(ival); case Long lval -> calculateLong(lval); default -> "unknown"; } System.out.println(result);
  • 61.
    Pattern matching ● Bettersolution to nasty if..else chains ● Fairly obvious to understand ● Plan is for more complex patterns over time
  • 62.
    Pattern matching ● Patternsexecuted in order, unlike current switch String result = switch (obj) { case String str && !str.isEmpty() -> calculateStr(str); case String str -> "empty string"; default "unknown"; } System.out.println(result);
  • 63.
    Pattern matching -my views ● All looks good so far ● Issues mostly tied up in expression switch
  • 64.
  • 65.
    Records ● No languagelevel access to "properties" in "bean" ● This limits pattern matching ● Concept to add "records" to solve this
  • 66.
    Records ● Short syntax ●Generated getters ● Generated equals/hashCode/toString ● Generated constructor ● Generated deconstructor
  • 67.
    Records ● http://cr.openjdk.java.net/~briangoetz/amber/datum.html "The APIfor a data class models the state, the whole state, and nothing but the state."
  • 68.
    Records ● Minimal syntax,maximum sugar record Person(String forename, String surname) {}; // creates fields // creates getters - forename(), surname() // creates equals/hashCode/toString // creates constructor/deconstructor
  • 69.
    Records ● Plain carriersfor data ○ the API of the class is fully coupled to the data ● No additional fields ● Can freely explode a record ○ Record <-> HashMap-like representation ○ constructor and deconstuctor ○ thus state cannot be hidden
  • 70.
    Records ● Quick todefine simple data interface Shape { } record Point(int x, int y); record Rect(Point p1, Point p2) implements Shape; record Circle(Point center, int radius) implements Shape;
  • 71.
    Records ● Fits intopattern matching switch (shape) { case Rect(Point(var x1, var y1), Point(var x2, var y2)):… case Circle(Point(var x, var y), var r): … … }
  • 72.
    Records ● Can adduser-defined methods ● Cannot replace equals/hashCode ● Can add additional constructors ● Cannot extend arbitrary class ● Can have static methods and fields ● Arrays are not well handled, use lists ● May be mutable, but may favour immutability
  • 73.
    Records - myviews ● Should be great, I still have some concerns ● Need to ensure support enough use cases ● Potential big cliff edge back to existing classes ● Class header syntax doesn't scale attractively ● Needs an abstraction across records and beans
  • 74.
  • 75.
    Value types ● JEP169 - http://openjdk.java.net/jeps/169 ● Future direction "Provide JVM infrastructure for working with immutable and reference-free objects, in support of efficient by-value computation with non-primitive types."
  • 76.
    Value types ● Referencetypes have identity ○ two String instances may be .equal() but not == ● Primitive types do not have identity ○ int 6 is always int 6 ● Value types are user-written code without identity
  • 77.
    Value types ● Considertwo LocalDate objects LocalDate date1 = LocalDate.of(2018, 4, 1); LocalDate date2 = LocalDate.of(2018, 4, 1); date1.equals(date2); // true date1 == date2; // false // this distinction is not helpful
  • 78.
    Value types ● Really,LocalDate should be a value type ● No actual requirement for identity ● Only need one "1st April 2018"
  • 79.
    Value types ● Nofirm syntax exists yet value Point(int x, int y); value Rect(Point p1, Point p2);
  • 80.
    Value types Rect memory: Header p1:reference pointer p2: reference pointer Point memory: Header x: int y: int Point memory: Header x: int y: int As objects today:
  • 81.
    Value types Rect memory: Header p1.x: int p1.y : int p2.x : int p2.y : int As values:
  • 82.
    Value types ● Noidentity, no == ● No synchronization ● Ability to optimize memory layout ○ potential performance boost ● Will need generics over value types ○ this is pretty complex in its own right
  • 83.
    Value types -my view ● Long term effort ● Good to see progress ● Direction improving over time
  • 84.
  • 85.
    Summary ● Lots oflanguage change on the way ● Give feedback if you can ○ particularly if you can actually provide data points ● Interesting times!
  • 86.
    Summary ● Project Amber: ○http://openjdk.java.net/projects/amber/ ○ Keep on giving feedback ● Stephen Colebourne: ○ @jodastephen - feedback & questions ○ http://blog.joda.org ● OpenGamma ○ Strata - open source market risk analytics ○ Cloud-hosted analytics for the derivatives market