Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

JCConf 2020 - New Java Features Released in 2020

In 2020, Java 14 and 15 are released with many great features, including ZGC, Shenandoah GC, helpful NullPointerExceptions, pattern matching for instanceof, switch expressions, text blocks, records, hidden classes, and sealed classes. They not only improve performance of GC and Java applications, but also introduce new syntax to ease our effort to write more readable and efficient code. Let's take a look at those features!

  • Be the first to comment

JCConf 2020 - New Java Features Released in 2020

  1. 1. New Java Features Released in 2020 Joseph Kuo (CyberJos) Director of Cloud @ Ayla 雲端技術總監 @ 艾拉物聯
  2. 2. About Me • 21 年 Java 經驗, 25+ 年軟⼯經驗 • 寫過 Basic, C/C++, LPC, JavaScript, Python 各式專案 • JCConf 2014, 2016, 2017, 2018 講師 • Oracle Groundbreakers 2019 講師 • 曾在連鎖資訊教育機構、加值簡訊服務商、雲端遊戲影⾳ 平台、全球電⼦商務網站、資安防護、及⽤⼾⾏為管理等 公司中任職 • 負責架構規劃、系統開發、軟體設計、程式撰寫以及技術 教學,並參與各式專案的規劃設計、開發實作與部署維護 • 希望能⼀輩⼦玩技術寫程式到老 2
  3. 3. Taiwan Java User Group • 官⽅網站: http://www.twjug.org • TWJUG 粉絲團: https://www.facebook.com/groups/twjug • LINE 社群「Java 交流討論區」: https://line.me/ti/g2/qNtYt-2d5ssCd2tcPBpIPA 3
  4. 4. Agenda • Overview • Syntax Changes • API Changes • Garbage Collector • Removal & Incubator • What’s Next? 4
  5. 5. Overview 5
  6. 6. JDK 13 (2019-09-17) • JEP 350: Dynamic CDS Archives • JEP 351: ZGC: Uncommit Unused Memory • JEP 353: Reimplement the Legacy Socket API • JEP 354: Switch Expressions (Preview) • JEP 355: Text Blocks (Preview) 6
  7. 7. JDK 14 (2020-03-17) • JEP 305: Pattern Matching for instanceof (Preview) • JEP 343: Packaging Tool (Incubator) • JEP 345: NUMA-Aware Memory Allocation for G1 • JEP 349: JFR Event Streaming • JEP 352: Non-Volatile Mapped Byte Buffers • JEP 358: Helpful NullPointerExceptions • JEP 359: Records (Preview) • JEP 362: Deprecate the Solaris and SPARC Ports 7
  8. 8. JDK 14 (2020-03-17) cont. • JEP 361: Switch Expressions (Standard) • JEP 363: Remove the CMS Garbage Collector • JEP 364: ZGC on macOS • JEP 365: ZGC on Windows • JEP 366: Deprecate the ParallelScavenge + SerialOld GC combination • JEP 367: Remove the Pack200 Tools and API • JEP 368: Text Blocks (Second Preview) • JEP 370: Foreign-Memory Access API (Incubator) 8
  9. 9. JDK 15 (2020-09-15) • JEP 339: Edwards-Curve Digital Signature Algorithm (EdDSA) • JEP 360: Sealed Classes (Preview) • JEP 371: Hidden Classes • JEP 372: Remove the Nashorn JavaScript Engine • JEP 373: Reimplement the Legacy DatagramSocket • JEP 374: Disable and Deprecate Biased Locking • JEP 375: Pattern Matching for instanceof (Preview) 9
  10. 10. JDK 15 (2020-09-15) cont. • JEP 377: ZGC: A Scalable Low-Latency GC • JEP 378: Text Blocks • JEP 379: Shenandoah: A Low-Pause-Time GC • JEP 381: Remove the Solaris and SPARC Ports • JEP 383: Foreign-Memory Access API (Incubator) • JEP 384: Records (Preview) • JEP 385: Deprecate RMI Activation for Removal 10
  11. 11. Syntax Changes 11
  12. 12. Switch Expressions • Preview: JEP 325 (JDK12), JEP 354 (JDK13) • Standard: JEP 361 (JDK14) • To extend switch to be either a statement or an expression so that both forms can use either traditional labels (with fall through) case ... : or new labels (with no fall through) case ... -> , with a further new statement for yielding a value from a switch expression. 12
  13. 13. Switch Expressions Syntax T result = switch(arg) { case label1 -> expression1; case label2 -> expression2; default -> expression3; } 13
  14. 14. Switch Statement - Before void showNumber(int i) { switch(i) { case 0: System.out.println("Zero"); break; case 1: System.out.println("One"); break; case 2: System.out.println("Two"); break; default: System.out.println(“Others"); break; } } 14
  15. 15. Switch Statement - After void showNumber(int i) { switch(i) { case 0 -> System.out.println("Zero"); case 1 -> System.out.println("One"); case 2 -> System.out.println("Two"); default -> System.out.println("Others"); } } 15
  16. 16. Switch Expressions Statement 16
  17. 17. Switch Expressions Assignment enum Month { JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC } int getDay(Month month) { int result = switch(month) { case JAN, MAR, MAY, JUL, AUG, OCT, DEC -> 31; case APR, JUN, SEP, NOV -> 30; case FEB -> 28; }; return result; } 17
  18. 18. Switch Expressions Assignment 18
  19. 19. Switch Expressions - yield • If a full block is needed, we can use the new yield statement to yield a value, which becomes the value of the enclosing switch expression. • When using a traditional switch block, values can also be yielded by using the new yield statement. 19
  20. 20. Switch Expressions - yield String result1 = switch (i) { case 0 -> "Zero"; default -> { String r = i % 2 == 0 ? "Even" : "Odd"; yield r; } } String result2 = switch (i) { case 0: yield "Zero"; case 1: yield "One"; default: yield "Unknown"; } 20
  21. 21. Switch Expressions - yield 21
  22. 22. Text Blocks • Preview: JEP 326 (JDK12), JEP 355 (JDK13), JEP 368 (JDK14) • Standard: JEP 378 (JDK15) • A multi-line string literal that avoids the need for most escape sequences, automatically formats the string in a predictable way, and gives the developer control over the format when desired. 22
  23. 23. Text Blocks - Before & After String json1 = "{n" + " "name": "Joseph",n" + " "gender": "M"n" + "}n"; String json2 = """ { "name": "Joseph", "gender": "M" } """; 23
  24. 24. Text Blocks - Before & After 24
  25. 25. Text Blocks - Usage // empty string String s1 = """ """; String s2 = """ """; String s3 = """ """; // no line terminator after opening delimiter String s4 = """"""; String s5 = """ """; 25
  26. 26. Text Blocks - New Line Diff. 26
  27. 27. Text Blocks - Indents 27
  28. 28. Text Blocks - Escape Character 28
  29. 29. Text Blocks - Escape Character 29
  30. 30. Pattern Matching for instanceof • Preview: JEP 305 (JDK14), JEP 375 (JDK15) • It enhances instanceof operators to allow common logic in a program, namely the conditional extraction of components from objects, to be expressed more concisely and safely 30
  31. 31. Pattern Matching - Before if (obj instanceof String) { // check String s = (String) obj; // assign + cast System.out.println("String: " + s); } else if (obj instanceof Integer) { Integer i = (Integer) obj; System.out.println("Integer: " + i); } else if (obj instanceof Map) { Map m = (Map) obj; System.out.println("Map: " + m); } 31
  32. 32. Pattern Matching - After if (obj instanceof String s) { //only use s here System.out.println("String: " + s); } else if (obj instanceof Integer i) { //no s here System.out.println("Integer: " + i); } else if (obj instanceof Map m) { System.out.println("Map: " + m); } 32
  33. 33. Pattern Matching - Conditions if (obj instanceof String s && s.length() > 1) { System.out.println("Text: " + s); } // PASS if (obj instanceof String s || s.length() > 1) { System.out.println("Text: " + s); } // ERROR 33
  34. 34. Pattern Matching - Conditions 34
  35. 35. Pattern Matching - equals() public class TestClass { private String s; public TestClass(String s) { this.s = s; } @Override public boolean equals(Object o) { if (o == this) { return true; } return o instanceof TestClass testClass && testClass.s.equals(this.s); } } 35
  36. 36. Records • Preview: JEP 359 (JDK14), JEP 384 (JDK15) • Classes that act as transparent carriers for immutable data. Records can be thought of as nominal tuples. • This new kind of class is to declare that a small group of variables is to be regarded as a new kind of entity. A record declares its state (the group of variables) and commits to an API that matches that state. 36
  37. 37. Records - Before class Point { private final int x, y; Point(int x, int y) { this.x = x; this.y = y; } int x() { return x; } int y() { return y; } public boolean equals(Object o) { return o instanceof Point && ((Point) o).x == x && ((Point) o).y == y; } public int hashCode() { return Objects.hash(x, y); } public String toString() { return String.format("Point[x=%d, y=%d]", x, y); } } 37
  38. 38. Records - After • The declaration of a record specifies a name, a header and a body. The header lists the components of the record, which are the variables that make up its state. record Point(int x, int y) { // body } 38
  39. 39. Records - Standard Members • For each component in the header: a public accessor method with the same name and return type as the component, and a private final field with the same type as the component • A canonical constructor whose signature is the same as the header • equals and hashCode methods which say that two records are equal if they are of the same type/value • A toString method that returns a string representation of all the record components along with their names 39
  40. 40. Records 40
  41. 41. Records - Restrictions • A record doesn't have an extends clause. The superclass is always java.lang.Record, like enum • A record is implicitly final and cannot be abstract • A record cannot explicitly declare instance fields, and cannot contain instance initializers. • The implicitly declared fields are final • A record cannot declare native methods. 41
  42. 42. Records - Behaviors • Instantiated with the new keyword • Can be declared top level or nested • Can declare static methods/fields/initializers • Can declare instance methods • Can implement interfaces • Can declare nested types, including nested records • Can be annotated 42
  43. 43. Records with static Members record Point(int x, int y) implements Serializable { private static int counter; public static int getCounter() { return counter; } public static void addCounter() { counter++; } public int plusX() { return counter * x;} } 43
  44. 44. Records with static Members 44
  45. 45. Records with Nested Builder record Point(int x, int y) { public static class Builder { private int x, y; public Builder withX(int x) { this.x = x; return this; } public Builder withY(int y) { this.y = y; return this; } public Point build() { return new Point(x, y);} } public static Builder newBuilder() { return new Builder(); } } Point p = Point.newBuilder().withX(2).withY(3).build(); 45
  46. 46. Records with Nested Builder 46
  47. 47. Sealed Classes • Preview: JEP 360 (JDK15) • Sealed classes and interfaces restrict which other classes or interfaces may extend or implement them. • Allow the author of a class or interface to control which code is responsible for implementing it. • Provide a more declarative way than access modifiers to restrict the use of a superclass • Support future directions in pattern matching by underpinning the exhaustive analysis of patterns 47
  48. 48. Sealed Classes Syntax public sealed interface Shape permits Circle, Rectangle, Square {} public final class Circle implements Shape {} public sealed class Rectangle implements Shape permits TransparentRectangle {} public final class TransparentRectangle extends Rectangle {} public record Square(int x, int y) implements Shape {} 48
  49. 49. Sealed Classes 49
  50. 50. Sealed Classes (future release) 50
  51. 51. API Changes 51
  52. 52. Helpful NullPointerException • It’s very hard to troubleshoot the root cause when NullPointerExceptions are thrown: • a.b.c.i = 99 • a[i][j][k] = 99 • a.i = b.j • a[i][j] = b[x][y] • a.getB().getC().getD() Exception java.lang.NullPointerException at (xxxx:10) 52
  53. 53. Helpful NullPointerException • a.b.c.i = 99 Exception in thread "main" java.lang.NullPointerException: Cannot read field "c" because "a.b" is null • a[i][j][k] = 99 Exception in thread "main" java.lang.NullPointerException: Cannot load from object array because "a[i][j]" is null • a.i = b.j Exception in thread "main" java.lang.NullPointerException: Cannot read field "j" because "b" is null • a[i][j] = b[x][y] Exception in thread "main" java.lang.NullPointerException: Cannot invoke "java.lang.Integer.intValue()" because "j" is null 53
  54. 54. Helpful NullPointerException • The first part is the consequence of the NPE. It says which action could not be performed because a bytecode instruction popped a null reference from the operand stack. • The second part is the reason for the NPE. It recreates the part of the source code that pushed the null reference on to the operand stack. 54
  55. 55. 1st Part of NPE Messages 55
  56. 56. 2nd Part of NPE Messages 56
  57. 57. Reimplement Socket • The implementations of java.net.Socket and java.net.ServerSocket have been reimplemented. The original used PlainSocketImpl from JDK1.0. Now they uses NioSocketImpl • Adding -Djdk.net.usePlainSocketImpl in JVM options can let you use the old version of Socket API. 57
  58. 58. Reimplement DatagramSocket • Replace the underlying implementations of the java.net.DatagramSocket & java.net.MulticastSocket APIs with simpler and more modern implementations that are easy to maintain and debug. 58
  59. 59. Hidden Classes • A kind of classes cannot be used directly by the bytecode of other classes. • They are intended for use by frameworks that generate classes at run time and use them indirectly, via reflection. • A hidden class may be defined as a member of an access control nest, and may be unloaded independently of other classes. 59
  60. 60. Garbage Collector 60
  61. 61. Numa-Aware Memory Allocation for G1 • Improve G1 performance on large machines by implementing NUMA-aware memory allocation 61
  62. 62. ZGC • JEP 333: ZGC: A Scalable Low-Latency Garbage Collector (Experimental) (JDK11) • JEP 351: ZGC: Uncommit Unused Memory • JEP 364: ZGC on macOS (JDK14) • JEP 365: ZGC on Windows (JDK14) • JEP 377: ZGC: A Scalable Low-Latency Garbage Collector (JDK15) 62
  63. 63. ZGC • It supports TB-level (8MB~16TB) GC with very low pause time (<10ms) by using colored pointer and read barriers, developed by Oracle. • ZGC is enabled now via the following command- line option: -XX:+UseZGC • Because ZGC is a product (non-experimental) feature, it means the option -XX:+UnlockExperimentalVMOptions will no longer be needed. 63
  64. 64. Shenandoah GC • It is a low-pause-time garbage collector from Red Hat, and supports AArch64 and Amd64. It is also low-pause-time. Unlike ZGC based on colored pointers, Shenandoah GC uses brooks pointers. • Shenandoah GC is enabled now via the following command-line option: -XX:+UseShenandoahGC • Because Shenandoah GC is a product (non- experimental) feature, it means the option -XX:+UnlockExperimentalVMOptions will no longer be needed. 64
  65. 65. Removal & Incubator 65
  66. 66. Removal/Deprecation of GC • Remove the Concurrent Mark Sweep (CMS) Garbage Collector in JEP 363 (JDK14) • Deprecated in JEP 291 (JDK9) • Deprecate the ParallelScavenge + SerialOld GC Combination in JEP 366 (JDK14) • The pairing of the parallel young generation GC and the serial old GC, enabled with -XX:+UseParallelGC -XX:-UseParallelOldGC • Very little used but requires a significant amount of maintenance effort 66
  67. 67. Removal/Deprecation of APIs • Solaris and SPARC Ports • Deprecated in JEP 362 (JDK14) • Removed in JEP 381 (JDK15) • Pack200 Tools and API • Introduced in JSR 200 (Java SE 5.0) • Last used in JDK8 • Deprecated in JEP 336 (JDK11) • Removed in JEP 367 (JDK14) 67
  68. 68. Removal/Deprecation of APIs • Nashorn JavaScript Engine • Introduced in JEP 174 (JDK8) • Deprecated in JEP 335 (JDK11) • Removed in JEP 372 (JDK15) • Disable and Deprecate Biased Locking (JDK 15) • RMI Activation mechanism (java.rmi.activation) • Rarely used in these years • Optional since JDK 8 • Deprecated in JEP 385 (JDK15) 68
  69. 69. Incubator - Packaging Tool • Create a tool for packaging self-contained Java applications • Support native packaging formats to give end users a natural installation experience • Windows: msi and exe • macOS: pkg and dmg • Linux: deb and rpm • Allow launch-time parameters to be specified at packaging time 69
  70. 70. Package Tool jpackage --help 70
  71. 71. Foreign-Memory Access API • Introduce an API to allow Java programs to safely and efficiently access foreign memory outside of the Java heap • The foreign-memory access API introduces three main abstractions: • MemorySegment • MemoryAddress • MemoryLayout 71
  72. 72. Foreign-Memory Access API VarHandle handle = MemoryHandles.varHandle(int.class, ByteOrder.nativeOrder()) try (MemorySegment seg = MemorySegment.allocateNative(100)) { MemoryAddress base = seg.baseAddress(); for (int i = 0; i < 25; i++) { MemoryAddress offset = base.addOffset(i * 4); handle.set(offset, i * 3); System.out.println( String.format("i: %d, o: %d, v: %d”, i, offset.segmentOffset(), handle.get(offset))); } } 72
  73. 73. Foreign-Memory Access API 73
  74. 74. What’s Next? 74
  75. 75. JDK 16 (2021-03-16) • JEP 338: Vector API (Incubator) • JEP 347: Enable C++14 Language Features • JEP 357: Migrate from Mercurial to Git • JEP 369: Migrate to GitHub • JEP 376: ZGC: Concurrent Thread-Stack Processing • JEP 380: Unix-Domain Socket Channels • JEP 386: Alpine Linux Port 75
  76. 76. JDK 16 (2021-03-16) cont. • JEP 387: Elastic Metaspace • JEP 388: Windows/AArch64 Port • JEP 392: Packaging Tool • JEP 393: Foreign-Memory Access API (3rd Incubator) • JEP 394: Pattern Matching for instanceof • JEP 395: Records 76
  77. 77. Thank you 77

×