According to Mark Reinhold we can expect (after Java 9) a time-based model with a new feature release every six months, update releases every quarter, and a long-term support release every three years. This session will have a closer look at the possible Java language features we can expect in the near future.
4. “For Java to remain competitive it
must not just continue to move
forward — it must move forward
faster.”
- Mark Reinhold , Chief Architect of the Java Platform Group at Oracle
5. @Stephan007
More Java Releases
• Every 6 months feature releases (March, September)
• Long-term support releases every 3 years
• Next release for March 2018
• Details @ https://mreinhold.org/blog/forward-faster
12. @Stephan007
Expanded Type Inference
List<String> empty = Collections.<String>emptyList();
List<String> empty = Collections.emptyList();
• Java 5: type inference for generic method type arguments
• Java 7: type inference for constructor type arguments
List<String> newList = new ArrayList<String>();
List<String> newList = new ArrayList<>();
• Java 8: type inference for lambda formals
Predicate<String> isEmpty = (String s) -> s.isEmpty();
Predicate<String> isEmpty = s -> s.isEmpty();
Brian Goetz @ http://bit.ly/2x3Wop9
13. @Stephan007
Local-Variable
Type Inference (JEP 286)
URL url = new URL(“https://devoxx.com");
URLConnection conn = url.openConnection();
Scanner scanner = new Scanner(conn.getInputStream(), “UTF-8”);
var url = new URL(“https://devoxx.com");
var conn = url.openConnection();
var scanner = new Scanner(conn.getInputStream(), “UTF-8”);
Brian Goetz @ http://bit.ly/2x3Wop9
14. @Stephan007
LVTI warnings
var x = { 1, 2, 3 }; // array initializer needs an explicit target-type
http://cr.openjdk.java.net/~mcimadamore/8177466/lvti-diags.html
var x = null; // variable initializer is 'null'
var x; // cannot use 'var' on variable without initializer
var x = m(x); // cannot use 'var' on self-referencing variable
class var { } // as of release 9, 'var' is a restricted local variable type
15. @Stephan007
LVTI warnings
var[] x = s; // ‘var' is not allowed as an element type of an array
http://cr.openjdk.java.net/~mcimadamore/8177466/lvti-diags.html
var x = 1, y = 2; // 'var' is not allowed in a compound declaration
var<String> list() { return null; } // illegal ref to restricted type 'var'
var x = () -> { }; // lambda expression needs an explicit target-type
16. @Stephan007
Hidden compiler option
-XDfind=local
Detect local variables whose declared type can be replaced by 'var'
http://mail.openjdk.java.net/pipermail/compiler-dev/2017-September/011060.html
class TestLVTI {
void test() {
String s2 = "";
for (String s = s2 ; s != "" ; ) { }
Object o = "";
}
}
TestLVTI.java:3: warning: Redundant type for local variable (replace
explicit type with 'var').
String s2 = "";
^
TestLVTI.java:4: warning: Redundant type for local variable (replace
explicit type with 'var').
for (String s = s2 ; s != "" ; ) { }
^
2 warnings
The type of o is not redundant!
17. @Stephan007
Other JVM Languages
Groovy Kotlin
def robot = new Robot() // mutable property
var name = “Hello”
// Read-only
// there's no 'new' keyword
val result = Address()
Scala & Lombok
// Mutable
var name = ”Hello”
// Read-only
val result = new Address()
BTW None of these JVM languages demand a semi-colon! 🤓
21. @Stephan007
Generic Enums
“Enhance the expressiveness of the enum construct in the
Java Language by allowing type-variables in enums, and
performing sharper type-checking for enum constants.”
- Maurizio Cimadamore
http://openjdk.java.net/jeps/301
22. @Stephan007
Enum enhancements
enum Argument<X> { // declares generic enum
STRING<String>(String.class),
INTEGER<Integer>(Integer.class), ... ;
Class<X> clazz;
Argument(Class<X> clazz) { this.clazz = clazz; }
Class<X> getClazz() { return clazz; }
}
Class<String> cs = Argument.STRING.getClazz(); //uses sharper typing of enum constant
http://openjdk.java.net/jeps/301
• Enum constants to carry constant-specific type information
• Constant-specific state and behavior.
24. @Stephan007
Treatment of underscores
• Use an uncerscore for unnamed lambda parameters
BiFunction<Integer, String, String> biss = (i, _) -> String.valueOf(i);
http://openjdk.java.net/jeps/302
25. @Stephan007
Shadowing a lambda parameter
• Allow lambda parameters to shadow variables in enclosing scopes.
• And locals declared with a lambda.
Map<String, Integer> msi = …
…
String key = computeSomeKey();
msi.comuteIfAbstent(key, key -> key.length()); // error!
http://openjdk.java.net/jeps/302
27. @Stephan007
String formatted = “unknown”;
if (constant instanceof Integer) {
int i = (Integer)constant;
formatted = String.format(“int %d”, i);
} else if (constant instanceof Byte) {
byte b = (Byte)constant;
formatted = String.format(“byte %d”, b);
} // …
https://www.voxxed.com/2017/08/pattern-matching-java/
28. @Stephan007
Pattern Matching
String formatted = “unknown”;
switch(constant) {
case Integer i :
formatted = String.format(“int %d”, i); break;
case Byte b :
formatted = String.format(“byte %d”, b); break;
// …
default: formatted = String.format(“Unknown: %s”, constant);
}
https://www.voxxed.com/2017/08/pattern-matching-java/
29. @Stephan007
Switch Expression
String formatted =
switch(constant) {
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 -> “Unknown”;
}
https://www.voxxed.com/2017/08/pattern-matching-java/
30. @Stephan007
Enhanced Switch Expression
Shape s = …
double area = switch (shape) {
case Circle(var center, var radius)
-> PI * radius * radius;
case Square(var lowerLeft, var edge)
-> edge * edge;
case Rect(var lowerLeft, var upperRight)
-> (upperRight.x - lowerLeft.x)
* (upperRight.y - lowerLeft.y);
// …
}
interface Shape { }
class Circle implements Shape {
Point center;
double radius;
}
class Square implements Shape {
Point lowerLeft;
double edge;
}
class Rect implements Shape {
Point lowerLeft;
Point upperRight;
}
JavaOne 2017 keynote : https://www.youtube.com/watch?v=Tf5rlIS6tkg
31. @Stephan007
val x = Random.nextInt(10)
val value = x match {
case 0 => “zero”
case 1 => "one"
case 2 => "two"
case _ => "many"
}
val value = when(x) {
0 -> “zero”
1 -> "one"
2 -> "two"
else -> "many"
}
35. @Stephan007
public class Point {
final int x;
final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public boolean equals(Object o) {
return o instanceof Point && x == ((Point)o).x && y == ((Point)o).y;
}
public int hashCode() {
return x + 31 * y;
}
public String toString() {
return String.format(“Point[%d,%d]”, x, y);
}
}
http://cr.openjdk.java.net/~jrose/values/values-0.html
38. @Stephan007
Value Types Requirements
• Final, not extensible
• Only interface parents
• Immutable fields
• No identity
• Equality based on state
• No recursive definitions
• Non-nullable values
• Value semantics
• No (representational) polymorphism
• Multiple fields supported
41. @Stephan007
Generic type arguments are
constrained to extend Object
• Supporting generic primitive and value types arguments!
class Box<T> {
private final T t;
public Box(T t) { this.t = t; }
public T get() { return t; }
}
http://openjdk.java.net/jeps/218
• Suppose we want to specialize the following class with T=int
42. @Stephan007
• Project Amber
• Project Valhalla
• Project Panama - Interconnecting JVM and native code
• Project Loom - Make Concurrency simple(r) again!
• Project Metropolis - The holy Graal