1
Java 14 Pattern Matching
Oleksandr Navka
Lead Software Engineer, Consultant, GlobalLogic
2
1. Updated instanceof
2. Updated switch-case
3. Java Records
Agenda
3
Тагир Валеев
JetBrains
Pattern matching
и его воображаемые друзья
4
5
When someone match something :)
What is pattern matching?
6
Any pattern
• _
Constant pattern
• 1
• true
• null
Type pattern
• String s
Var pattern
• var i = 1
Deconstruction pattern
• Optional(String s)
• Node(Node left, Node right)
What are the patterns?
7
Instanceof
8
public class Animal {
}
class Dog extends Animal {
public void bark() {
}
}
class Cat extends Animal {
public void meow() {
}
}
9
public static void say(Animal animal) {
if (animal instanceof Dog) {
Dog dog = (Dog) animal;
dog.bark();
} else if (animal instanceof Cat) {
Cat cat = (Cat) animal;
cat.meow();
}
}
10
public static void say(Animal animal) {
if (animal instanceof Dog) {
Dog dog = (Dog) animal;
dog.bark();
} else if (animal instanceof Cat) {
Cat cat = (Cat) animal;
cat.meow();
}
}
11
public static void say(Animal animal) {
if (animal instanceof Dog dog) {
dog.bark();
} else if (animal instanceof Cat cat) {
cat.meow();
}
}
12
public static void say(Animal animal) {
if (animal instanceof Dog dog) {
dog.bark();
} else if (animal instanceof Cat cat) {
cat.meow();
}
}
13
Before:
expression istanceof Type
Now:
expression instanceof Pattern
14
Scoping
15
if (obj instanceof String s) {
// can use s here
} else {
// can't use s here
}
16
if (obj instanceof String s) {
// can use s here
} else {
// can't use s here
}
binding variable
17
if (!(obj instanceof String s)) {
} else {
s.contains("a")
}
18
if(obj instanceof String s && s.length() > 5) {
System.out.println(s.toUpperCase());
}
19
if(obj instanceof String s || s.length() > 5) {
System.out.println(s.toUpperCase());
}
20
if(!(obj instanceof String s) || s.length() > 5) {
System.out.println("Do something");
} else {
System.out.println(s.toUpperCase());
}
21
if(!(obj instanceof String s) || s.length() > 5) {
System.out.println("Do something");
} else {
System.out.println(s.toUpperCase());
}
22
if(!(obj instanceof String s) || s.length() > 5) {
throw new IllegalArgumentException();
}
System.out.println(s.toUpperCase());
23
if(!(obj instanceof String s) || s.length() > 5) {
throw new IllegalArgumentException();
}
System.out.println(s.toUpperCase());
24
if (!(obj instanceof String s)) {
s.contains(..)
} else {
s.contains(..)
}
25
private String s = "abc";
if (!(obj instanceof String s)) {
s.contains(..)
} else {
s.contains(..)
}
26
1. if (obj instanceof String s) {s.trim()}
2. if (!(obj instanceof String s)) {} else {s.contains("a")}
3. if(obj instanceof String s && s.length() > 5) {}
4. if(obj instanceof String s || s.length() > 5) {}
Binding variable scope
27
1. if (obj instanceof String s) {s.trim()}
2. if (!(obj instanceof String s)) {} else {s.contains("a")}
3. if(obj instanceof String s && s.length() > 5) {}
4. if(obj instanceof String s || s.length() > 5) {}
Binding variable scope
28
1. if (obj instanceof String s) {s.trim()}
2. if (!(obj instanceof String s)) {} else {s.contains("a")}
3. if(obj instanceof String s && s.length() > 5) {}
4. if(obj instanceof String s || s.length() > 5) {}
5. if(!(obj instanceof String s) || s.length() > 5) {}
6. if(!(obj instanceof String s) || s.length() > 5) {} else {s.toUpperCase());}
7. if(!(obj instanceof String s) || s.length() > 5) {
throw new IllegalArgumentException();
}
System.out.println(s.toUpperCase());
Binding variable scope
29
1. instanceof has got type pattern matching
2. instanceof the first java feature that got pattern matching
3. Be aware about scoping
Instanceof Summary
30
Switch - case
31
public enum ProgrammingParadigm {OBJECT_ORIENTED, PROCEDURAL, FUNCTIONAL}
public static List<String> getProgrammingLanguage(ProgrammingParadigm programmingParadigm) {
List<String> languages = new ArrayList<>();
switch (programmingParadigm) {
case OBJECT_ORIENTED:
languages.add("Java");
languages.add("C++");
break;
case FUNCTIONAL:
languages.add("Haskel");
break;
case PROCEDURAL:
languages.add("Pascal");
break;
}
return languages;
}
Old version of switch
32
public enum ProgrammingParadigm {OBJECT_ORIENTED, PROCEDURAL, FUNCTIONAL}
public static List<String> getProgrammingLanguage(ProgrammingParadigm programmingParadigm) {
List<String> languages = new ArrayList<>();
switch (programmingParadigm) {
case OBJECT_ORIENTED:
languages.add("Java");
languages.add("C++");
break;
case FUNCTIONAL:
languages.add("Haskel");
break;
case PROCEDURAL:
languages.add("Pascal");
break;
}
return languages;
}
Old version of switch
33
public enum ProgrammingParadigm {OBJECT_ORIENTED, PROCEDURAL, FUNCTIONAL}
public static List<String> getProgrammingLanguage(ProgrammingParadigm programmingParadigm) {
List<String> languages = new ArrayList<>();
switch (programmingParadigm) {
case OBJECT_ORIENTED:
languages.add("Java");
languages.add("C++");
break;
case FUNCTIONAL:
languages.add("Haskel");
break;
case PROCEDURAL:
languages.add("Pascal");
break;
}
return languages;
}
Old version of switch
Input type limitations:
byte, short, char, and int
Enum Types, String
34
public enum ProgrammingParadigm {OBJECT_ORIENTED, PROCEDURAL, FUNCTIONAL}
public static List<String> getProgrammingLanguage(ProgrammingParadigm programmingParadigm) {
List<String> languages = new ArrayList<>();
switch (programmingParadigm) {
case OBJECT_ORIENTED:
languages.add("Java");
languages.add("C++");
break;
case FUNCTIONAL:
languages.add("Haskel");
break;
case PROCEDURAL:
languages.add("Pascal");
break;
}
return languages;
}
Old version of switch
Can’t
get
result
35
public static List<String> getProgrammingLanguage(ProgrammingParadigm programmingParadigm) {
switch (programmingParadigm) {
case OBJECT_ORIENTED:
return List.of("Java", "C++");
case FUNCTIONAL:
return List.of("Haskel");
case PROCEDURAL:
return List.of("Pascal");
default:
return List.of();
}
}
36
public static List<String> getProgrammingLanguage(ProgrammingParadigm programmingParadigm) {
switch (programmingParadigm) {
case OBJECT_ORIENTED:
return List.of("Java", "C++");
case FUNCTIONAL:
return List.of("Haskel");
case PROCEDURAL:
return List.of("Pascal");
default:
return List.of();
}
}
37
Disadvantages:
1. Always remember about break
2. Input data type limitation
3. Can’t get result
4. Don’t understand all possible options for enum
Old version of switch
38
Pattern matching with switch case
39
public void printObject(Object obj) {
switch (obj) {
case String s:
System.out.println("This is String" + s.trim());
break;
case Integer i:
System.out.println("This is Integer" + i);
break;
case Number n:
System.out.println("This is number"+ n);
break;
default:
System.out.println("I don't know");
}
}
40
public void printObject(Object obj) {
switch (obj) {
case String s:
System.out.println("This is String" + s.trim());
break;
case Number n:
System.out.println("This is number"+ n);
break;
case Integer i:
System.out.println("This is Integer" + i);
break;
default:
System.out.println("I don't know");
}
}
41
public void printObject(Object obj) {
switch (obj) {
case String s:
System.out.println("This is String" + s.trim());
break;
default:
System.out.println("I don't know");
case Number n:
System.out.println("This is number"+ n);
break;
case Integer i:
System.out.println("This is Integer" + i);
break;
}
}
42
Updated switch case
43
public static List<String> getProgrammingLanguage(ProgrammingParadigm programmingParadigm) {
return switch (programmingParadigm) {
case OBJECT_ORIENTED -> List.of("Java", "C++");
case FUNCTIONAL -> List.of("Haskel");
case PROCEDURAL -> List.of("Pascal");
};
}
Updated switch case
44
public static List<String> getProgrammingLanguage(ProgrammingParadigm programmingParadigm) {
return switch (programmingParadigm) {
case OBJECT_ORIENTED -> {
System.out.println("You are master of polymorphism");
yield List.of("Java", "C++");
}
case FUNCTIONAL -> {
System.out.println("You are master of recursion");
yield List.of("Haskel");
}
case PROCEDURAL -> {
System.out.println("Try to use another paradigms");
yield List.of("Pascal");
}
};
}
45
1. Don’t need to use break
2. Can return result
3. Don’t need to use default branch if all options described
4. Input data types have limitations
Summary of updated switch
46
Java Records
47
private record Car(int speed, String manufacturer) {
}
Java Records
48
private record Car(int speed, String manufacturer) {
}
public static void main(String[] args) {
Car car = new Car(100, "Mercedes");
System.out.println(car.speed());
System.out.println(car.manufacturer());
}
Java Records
49
private record Car(int speed, String manufacturer) {
}
public static void main(String[] args) {
Car car = new Car(100, "Mercedes");
System.out.println(car);
}
-------
Output:
Car[speed=100, manufacturer=Mercedes]
Java Records
50
private static final class Car extends java.lang.Record {
private final int speed;
private final java.lang.String manufacturer;
public Car(int speed, java.lang.String manufacturer) { /* compiled code */ }
public java.lang.String toString() { /* compiled code */ }
public final int hashCode() { /* compiled code */ }
public final boolean equals(java.lang.Object o) { /* compiled code */ }
public int speed() { /* compiled code */ }
public java.lang.String manufacturer() { /* compiled code */ }
}
51
private static final class Car extends java.lang.Record {
private final int speed;
private final java.lang.String manufacturer;
public Car(int speed, java.lang.String manufacturer) { /* compiled code */ }
public java.lang.String toString() { /* compiled code */ }
public final int hashCode() { /* compiled code */ }
public final boolean equals(java.lang.Object o) { /* compiled code */ }
public int speed() { /* compiled code */ }
public java.lang.String manufacturer() { /* compiled code */ }
}
52
public abstract class Record {
protected Record() {}
@Override
public abstract boolean equals(Object obj);
@Override
public abstract int hashCode();
@Override
public abstract String toString();
}
53
private static final class Car extends java.lang.Record {
private final int speed;
private final java.lang.String manufacturer;
public Car(int speed, java.lang.String manufacturer) { /* compiled code */ }
public java.lang.String toString() { /* compiled code */ }
public final int hashCode() { /* compiled code */ }
public final boolean equals(java.lang.Object o) { /* compiled code */ }
public int speed() { /* compiled code */ }
public java.lang.String manufacturer() { /* compiled code */ }
}
54
private static final class Car extends java.lang.Record {
private final int speed;
private final java.lang.String manufacturer;
public Car(int speed, java.lang.String manufacturer) { /* compiled code */ }
public java.lang.String toString() { /* compiled code */ }
public final int hashCode() { /* compiled code */ }
public final boolean equals(java.lang.Object o) { /* compiled code */ }
public int speed() { /* compiled code */ }
public java.lang.String manufacturer() { /* compiled code */ }
}
55
private record Car(int speed, String manufacturer) {
public Car {
if(speed < 0) {
throw new IllegalArgumentException();
}
}
}
public static void main(String[] args) {
var car = new Car(-2, "Mercedes");
System.out.println(car);
}
Canonical constructor
56
private record Car(int speed, String manufacturer) {
public Car {
if(speed < 0) {
throw new IllegalArgumentException();
}
}
public Car(String manufacturer) {
this(0, manufacturer);
}
}
Canonical constructor
57
private static final class Car extends java.lang.Record {
private final int speed;
private final java.lang.String manufacturer;
public Car(int speed, java.lang.String manufacturer) { /* compiled code */ }
public java.lang.String toString() { /* compiled code */ }
public final int hashCode() { /* compiled code */ }
public final boolean equals(java.lang.Object o) { /* compiled code */ }
public int speed() { /* compiled code */ }
public java.lang.String manufacturer() { /* compiled code */ }
}
58
private static final class Car extends java.lang.Record {
private final int speed;
private final java.lang.String manufacturer;
public Car(int speed, java.lang.String manufacturer) { /* compiled code */ }
public java.lang.String toString() { /* compiled code */ }
public final int hashCode() { /* compiled code */ }
public final boolean equals(java.lang.Object o) { /* compiled code */ }
public int speed() { /* compiled code */ }
public java.lang.String manufacturer() { /* compiled code */ }
}
59
1. Java 14 present first version of pattern matching
2. Type pattern matching present in instanceof operator
3. New Switch statement was released with some blanks for
pattern matching
4. Keep eye on Java Records and deconstruction patterns
Summary
60
Thank You

Pattern Matching in Java 14

  • 1.
    1 Java 14 PatternMatching Oleksandr Navka Lead Software Engineer, Consultant, GlobalLogic
  • 2.
    2 1. Updated instanceof 2.Updated switch-case 3. Java Records Agenda
  • 3.
    3 Тагир Валеев JetBrains Pattern matching иего воображаемые друзья
  • 4.
  • 5.
    5 When someone matchsomething :) What is pattern matching?
  • 6.
    6 Any pattern • _ Constantpattern • 1 • true • null Type pattern • String s Var pattern • var i = 1 Deconstruction pattern • Optional(String s) • Node(Node left, Node right) What are the patterns?
  • 7.
  • 8.
    8 public class Animal{ } class Dog extends Animal { public void bark() { } } class Cat extends Animal { public void meow() { } }
  • 9.
    9 public static voidsay(Animal animal) { if (animal instanceof Dog) { Dog dog = (Dog) animal; dog.bark(); } else if (animal instanceof Cat) { Cat cat = (Cat) animal; cat.meow(); } }
  • 10.
    10 public static voidsay(Animal animal) { if (animal instanceof Dog) { Dog dog = (Dog) animal; dog.bark(); } else if (animal instanceof Cat) { Cat cat = (Cat) animal; cat.meow(); } }
  • 11.
    11 public static voidsay(Animal animal) { if (animal instanceof Dog dog) { dog.bark(); } else if (animal instanceof Cat cat) { cat.meow(); } }
  • 12.
    12 public static voidsay(Animal animal) { if (animal instanceof Dog dog) { dog.bark(); } else if (animal instanceof Cat cat) { cat.meow(); } }
  • 13.
  • 14.
  • 15.
    15 if (obj instanceofString s) { // can use s here } else { // can't use s here }
  • 16.
    16 if (obj instanceofString s) { // can use s here } else { // can't use s here } binding variable
  • 17.
    17 if (!(obj instanceofString s)) { } else { s.contains("a") }
  • 18.
    18 if(obj instanceof Strings && s.length() > 5) { System.out.println(s.toUpperCase()); }
  • 19.
    19 if(obj instanceof Strings || s.length() > 5) { System.out.println(s.toUpperCase()); }
  • 20.
    20 if(!(obj instanceof Strings) || s.length() > 5) { System.out.println("Do something"); } else { System.out.println(s.toUpperCase()); }
  • 21.
    21 if(!(obj instanceof Strings) || s.length() > 5) { System.out.println("Do something"); } else { System.out.println(s.toUpperCase()); }
  • 22.
    22 if(!(obj instanceof Strings) || s.length() > 5) { throw new IllegalArgumentException(); } System.out.println(s.toUpperCase());
  • 23.
    23 if(!(obj instanceof Strings) || s.length() > 5) { throw new IllegalArgumentException(); } System.out.println(s.toUpperCase());
  • 24.
    24 if (!(obj instanceofString s)) { s.contains(..) } else { s.contains(..) }
  • 25.
    25 private String s= "abc"; if (!(obj instanceof String s)) { s.contains(..) } else { s.contains(..) }
  • 26.
    26 1. if (objinstanceof String s) {s.trim()} 2. if (!(obj instanceof String s)) {} else {s.contains("a")} 3. if(obj instanceof String s && s.length() > 5) {} 4. if(obj instanceof String s || s.length() > 5) {} Binding variable scope
  • 27.
    27 1. if (objinstanceof String s) {s.trim()} 2. if (!(obj instanceof String s)) {} else {s.contains("a")} 3. if(obj instanceof String s && s.length() > 5) {} 4. if(obj instanceof String s || s.length() > 5) {} Binding variable scope
  • 28.
    28 1. if (objinstanceof String s) {s.trim()} 2. if (!(obj instanceof String s)) {} else {s.contains("a")} 3. if(obj instanceof String s && s.length() > 5) {} 4. if(obj instanceof String s || s.length() > 5) {} 5. if(!(obj instanceof String s) || s.length() > 5) {} 6. if(!(obj instanceof String s) || s.length() > 5) {} else {s.toUpperCase());} 7. if(!(obj instanceof String s) || s.length() > 5) { throw new IllegalArgumentException(); } System.out.println(s.toUpperCase()); Binding variable scope
  • 29.
    29 1. instanceof hasgot type pattern matching 2. instanceof the first java feature that got pattern matching 3. Be aware about scoping Instanceof Summary
  • 30.
  • 31.
    31 public enum ProgrammingParadigm{OBJECT_ORIENTED, PROCEDURAL, FUNCTIONAL} public static List<String> getProgrammingLanguage(ProgrammingParadigm programmingParadigm) { List<String> languages = new ArrayList<>(); switch (programmingParadigm) { case OBJECT_ORIENTED: languages.add("Java"); languages.add("C++"); break; case FUNCTIONAL: languages.add("Haskel"); break; case PROCEDURAL: languages.add("Pascal"); break; } return languages; } Old version of switch
  • 32.
    32 public enum ProgrammingParadigm{OBJECT_ORIENTED, PROCEDURAL, FUNCTIONAL} public static List<String> getProgrammingLanguage(ProgrammingParadigm programmingParadigm) { List<String> languages = new ArrayList<>(); switch (programmingParadigm) { case OBJECT_ORIENTED: languages.add("Java"); languages.add("C++"); break; case FUNCTIONAL: languages.add("Haskel"); break; case PROCEDURAL: languages.add("Pascal"); break; } return languages; } Old version of switch
  • 33.
    33 public enum ProgrammingParadigm{OBJECT_ORIENTED, PROCEDURAL, FUNCTIONAL} public static List<String> getProgrammingLanguage(ProgrammingParadigm programmingParadigm) { List<String> languages = new ArrayList<>(); switch (programmingParadigm) { case OBJECT_ORIENTED: languages.add("Java"); languages.add("C++"); break; case FUNCTIONAL: languages.add("Haskel"); break; case PROCEDURAL: languages.add("Pascal"); break; } return languages; } Old version of switch Input type limitations: byte, short, char, and int Enum Types, String
  • 34.
    34 public enum ProgrammingParadigm{OBJECT_ORIENTED, PROCEDURAL, FUNCTIONAL} public static List<String> getProgrammingLanguage(ProgrammingParadigm programmingParadigm) { List<String> languages = new ArrayList<>(); switch (programmingParadigm) { case OBJECT_ORIENTED: languages.add("Java"); languages.add("C++"); break; case FUNCTIONAL: languages.add("Haskel"); break; case PROCEDURAL: languages.add("Pascal"); break; } return languages; } Old version of switch Can’t get result
  • 35.
    35 public static List<String>getProgrammingLanguage(ProgrammingParadigm programmingParadigm) { switch (programmingParadigm) { case OBJECT_ORIENTED: return List.of("Java", "C++"); case FUNCTIONAL: return List.of("Haskel"); case PROCEDURAL: return List.of("Pascal"); default: return List.of(); } }
  • 36.
    36 public static List<String>getProgrammingLanguage(ProgrammingParadigm programmingParadigm) { switch (programmingParadigm) { case OBJECT_ORIENTED: return List.of("Java", "C++"); case FUNCTIONAL: return List.of("Haskel"); case PROCEDURAL: return List.of("Pascal"); default: return List.of(); } }
  • 37.
    37 Disadvantages: 1. Always rememberabout break 2. Input data type limitation 3. Can’t get result 4. Don’t understand all possible options for enum Old version of switch
  • 38.
  • 39.
    39 public void printObject(Objectobj) { switch (obj) { case String s: System.out.println("This is String" + s.trim()); break; case Integer i: System.out.println("This is Integer" + i); break; case Number n: System.out.println("This is number"+ n); break; default: System.out.println("I don't know"); } }
  • 40.
    40 public void printObject(Objectobj) { switch (obj) { case String s: System.out.println("This is String" + s.trim()); break; case Number n: System.out.println("This is number"+ n); break; case Integer i: System.out.println("This is Integer" + i); break; default: System.out.println("I don't know"); } }
  • 41.
    41 public void printObject(Objectobj) { switch (obj) { case String s: System.out.println("This is String" + s.trim()); break; default: System.out.println("I don't know"); case Number n: System.out.println("This is number"+ n); break; case Integer i: System.out.println("This is Integer" + i); break; } }
  • 42.
  • 43.
    43 public static List<String>getProgrammingLanguage(ProgrammingParadigm programmingParadigm) { return switch (programmingParadigm) { case OBJECT_ORIENTED -> List.of("Java", "C++"); case FUNCTIONAL -> List.of("Haskel"); case PROCEDURAL -> List.of("Pascal"); }; } Updated switch case
  • 44.
    44 public static List<String>getProgrammingLanguage(ProgrammingParadigm programmingParadigm) { return switch (programmingParadigm) { case OBJECT_ORIENTED -> { System.out.println("You are master of polymorphism"); yield List.of("Java", "C++"); } case FUNCTIONAL -> { System.out.println("You are master of recursion"); yield List.of("Haskel"); } case PROCEDURAL -> { System.out.println("Try to use another paradigms"); yield List.of("Pascal"); } }; }
  • 45.
    45 1. Don’t needto use break 2. Can return result 3. Don’t need to use default branch if all options described 4. Input data types have limitations Summary of updated switch
  • 46.
  • 47.
    47 private record Car(intspeed, String manufacturer) { } Java Records
  • 48.
    48 private record Car(intspeed, String manufacturer) { } public static void main(String[] args) { Car car = new Car(100, "Mercedes"); System.out.println(car.speed()); System.out.println(car.manufacturer()); } Java Records
  • 49.
    49 private record Car(intspeed, String manufacturer) { } public static void main(String[] args) { Car car = new Car(100, "Mercedes"); System.out.println(car); } ------- Output: Car[speed=100, manufacturer=Mercedes] Java Records
  • 50.
    50 private static finalclass Car extends java.lang.Record { private final int speed; private final java.lang.String manufacturer; public Car(int speed, java.lang.String manufacturer) { /* compiled code */ } public java.lang.String toString() { /* compiled code */ } public final int hashCode() { /* compiled code */ } public final boolean equals(java.lang.Object o) { /* compiled code */ } public int speed() { /* compiled code */ } public java.lang.String manufacturer() { /* compiled code */ } }
  • 51.
    51 private static finalclass Car extends java.lang.Record { private final int speed; private final java.lang.String manufacturer; public Car(int speed, java.lang.String manufacturer) { /* compiled code */ } public java.lang.String toString() { /* compiled code */ } public final int hashCode() { /* compiled code */ } public final boolean equals(java.lang.Object o) { /* compiled code */ } public int speed() { /* compiled code */ } public java.lang.String manufacturer() { /* compiled code */ } }
  • 52.
    52 public abstract classRecord { protected Record() {} @Override public abstract boolean equals(Object obj); @Override public abstract int hashCode(); @Override public abstract String toString(); }
  • 53.
    53 private static finalclass Car extends java.lang.Record { private final int speed; private final java.lang.String manufacturer; public Car(int speed, java.lang.String manufacturer) { /* compiled code */ } public java.lang.String toString() { /* compiled code */ } public final int hashCode() { /* compiled code */ } public final boolean equals(java.lang.Object o) { /* compiled code */ } public int speed() { /* compiled code */ } public java.lang.String manufacturer() { /* compiled code */ } }
  • 54.
    54 private static finalclass Car extends java.lang.Record { private final int speed; private final java.lang.String manufacturer; public Car(int speed, java.lang.String manufacturer) { /* compiled code */ } public java.lang.String toString() { /* compiled code */ } public final int hashCode() { /* compiled code */ } public final boolean equals(java.lang.Object o) { /* compiled code */ } public int speed() { /* compiled code */ } public java.lang.String manufacturer() { /* compiled code */ } }
  • 55.
    55 private record Car(intspeed, String manufacturer) { public Car { if(speed < 0) { throw new IllegalArgumentException(); } } } public static void main(String[] args) { var car = new Car(-2, "Mercedes"); System.out.println(car); } Canonical constructor
  • 56.
    56 private record Car(intspeed, String manufacturer) { public Car { if(speed < 0) { throw new IllegalArgumentException(); } } public Car(String manufacturer) { this(0, manufacturer); } } Canonical constructor
  • 57.
    57 private static finalclass Car extends java.lang.Record { private final int speed; private final java.lang.String manufacturer; public Car(int speed, java.lang.String manufacturer) { /* compiled code */ } public java.lang.String toString() { /* compiled code */ } public final int hashCode() { /* compiled code */ } public final boolean equals(java.lang.Object o) { /* compiled code */ } public int speed() { /* compiled code */ } public java.lang.String manufacturer() { /* compiled code */ } }
  • 58.
    58 private static finalclass Car extends java.lang.Record { private final int speed; private final java.lang.String manufacturer; public Car(int speed, java.lang.String manufacturer) { /* compiled code */ } public java.lang.String toString() { /* compiled code */ } public final int hashCode() { /* compiled code */ } public final boolean equals(java.lang.Object o) { /* compiled code */ } public int speed() { /* compiled code */ } public java.lang.String manufacturer() { /* compiled code */ } }
  • 59.
    59 1. Java 14present first version of pattern matching 2. Type pattern matching present in instanceof operator 3. New Switch statement was released with some blanks for pattern matching 4. Keep eye on Java Records and deconstruction patterns Summary
  • 60.