Java 12-17 features
The following is Java 12-17 syntax features:
Text Blocks
Syntax example
String iliadQuote = """
"But raging still, amidst his navy sat
The stern Achilles, stedfast in his hate;
Nor mix’d in combat, nor in council join’d;
But wasting cares lay heavy on his mind:
In his black thoughts revenge and slaughter roll,
And scenes of blood rise dreadful in his soul."
""";
SQL example
String query = """
SELECT "EMP_ID", "LAST_NAME" FROM "EMPLOYEE_TB"
WHERE "CITY" = 'INDIANAPOLIS'
ORDER BY "EMP_ID", "LAST_NAME";
""";
HTML example
String html = """
<html>
<body>
<p>Hello, world</p>
</body>
</html>
""";
Quotes example
String example = """
You can use "single" or ""double"" quotes any time you like.
But you must escape one if you want triple quotes: \""""
or \"\""" if you want four.
The line after me will be directly concatenated onto the same line\
But this line will preserve a single trailing space at the end\s
And this line will keep six trailing spaces \s
""";
Switch Expressions
New Syntax:
// assign the group of the given planet to a variable
String group = switch (planet) {
case MERCURY, VENUS, EARTH, MARS -> "inner planet";
case JUPITER, SATURN, URANUS, NEPTUNE -> "outer planet";
};
Yield value
// print the group of the given planet, and some more info,
// and assign the group of the given planet to a variable
String group = switch (planet) {
case EARTH, MARS -> {
System.out.println("inner planet");
System.out.println("made up mostly of rock");
yield "inner";
}
case JUPITER, SATURN -> {
System.out.println("outer planet");
System.out.println("ball of gas");
yield "outer";
}
};
Enhanced Switch statement
// print the group of the given planet
// without returning anything
switch (planet) {
case EARTH, MARS -> System.out.println("inner planet");
case JUPITER, SATURN -> System.out.println("outer planet");
}
Pattern Matching for instanceof
Syntax Example
Object o = "string disguised as object";
if (o instanceof String s) {
System.out.println(s.toUpperCase());
}
Complex if
if (o instanceof String s && !s.isEmpty()) {
System.out.println(s.toUpperCase());
}
Scope
if (!(o instanceof String s)) {
throw new RuntimeException("expecting string");
}
// s is in scope here!
System.out.println(s.toUpperCase());
Records
Syntax
record Point(int x, int y) { }
Usage
// canonical constructor
Point p = new Point(1, 2);
// getters - without "get" prefix
p.x();
p.y();
// equals / hashCode / toString
p.equals(new Point(1, 2)); // true
p.hashCode(); // depends on values of x and y
p.toString(); // Point[x=1, y=2]
Overriding
record Point(int x, int y) {
// explicit canonical constructor
Point {
// custom validations
if (x < 0 || y < 0)
throw new IllegalArgumentException("no negative points allowed");
// custom adjustments (usually counter-intuitive)
x += 1000;
y += 1000;
// assignment to fields happens automatically at the end
}
// explicit accessor
public int x() {
// custom code here...
return this.x;
}
}
Local records
public void withLocalRecord() {
record Point(int x, int y) { };
Point p = new Point(1, 2);
}
Sealed classes
Syntax
public sealed class Parent
permits ChildA, ChildB, ChildC { ... }
Interface
sealed interface Parent
permits ChildA, ChildB, ChildC { ... }
Without permits
public sealed class Parent {
final class Child1 extends Parent {}
final class Child2 extends Parent {}
final class Child3 extends Parent {}
}
Non-sealed
interface I {}
sealed class C permits D, E {}
non-sealed class D extends C {}
final class E extends C {}
void test (C c) {
if (c instanceof I)
System.out.println("It's an I");
}