4. Introduction
● Java continues to develop
● 3½ years from Java 8 to Java 9
● Too slow!
● New plan is to release Java every six months
5. 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
...
6. 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
...
7. 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
...
8. 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
9. 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!)
10. Local Variable Type Inference
https://www.flickr.com/photos/jodastephen/22471104851/
11. 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."
12. Local Variable Type Inference
● New keyword var
Path path = Paths.get("/src/main/java/module-info.java");
List<String> lines = Files.readAllLines(path);
13. Local Variable Type Inference
● New keyword var
Path path = Paths.get("/src/main/java/module-info.java");
List<String> lines = Files.readAllLines(path);
14. Local Variable Type Inference
● New keyword var
var path = Paths.get("/src/main/java/module-info.java");
var lines = Files.readAllLines(path);
15. Local Variable Type Inference
● New keyword var
var path = Paths.get("/src/main/java/module-info.java");
var lines = Files.readAllLines(path);
16. 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>
17. Local Variable Type inference
● Local variables only
○ cannot change method signatures
○ cannot change fields
● Variable still has a type
○ not like JavaScript
18. 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!
}
19. ● 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
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
public void 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
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
30. 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);
}
31. 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);
}
32. 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,
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
35. 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."
36. 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);
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
● 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
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
● New type 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
● Comma separate shared cases
var action = switch (trafficLight) {
case RED, YELLOW -> "Stop";
case GREEN -> "Go";
}
49. Expression switch
● May be able to handle null
var action = switch (trafficLight) {
case null -> "Panic!!!";
case RED -> "Stop";
case YELLOW -> "SlowAndStop";
case GREEN -> "Go";
}
50. What does this do?
● 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
54. 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."
55. 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);
56. 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);
57. 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);
58. 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);
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
● Combines with 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
● Better solution to nasty if..else chains
● Fairly obvious to understand
● Plan is for more complex patterns over time
62. 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);
63. Pattern matching - my views
● All looks good so far
● Issues mostly tied up in expression switch
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 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
70. 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;
71. 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): …
…
}
72. 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
73. 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
75. 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."
76. 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
77. 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
78. Value types
● Really, LocalDate should be a value type
● No actual requirement for identity
● Only need one "1st April 2018"
79. Value types
● No firm 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:
82. 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
83. Value types - my view
● Long term effort
● Good to see progress
● Direction improving over time
85. Summary
● Lots of language 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