This presentation slides were used at JJUG (Japan Java User Group) night seminar, which was held in the form of virtual conference on September 28, 2020. This deck is written in Japanese.
11. JDK 15までのJEPの個数 – # of JEPs in each release
blogs.oracle.com/java-platform-group/the-arrival-of-java-15
12. JDK 15に取り込まれたJEP – JEPs in JDK 15
openjdk.java.net/projects/jdk/15/
339 Edwards-Curve Digital Signature Algorithm (EdDSA)
360 Sealed Classes (Preview)
371 Hidden Classes
372 Remove the Nashorn JavaScript Engine
373 Reimplement the Legacy DatagramSocket API
374 Disable and Deprecate Biased Locking
375 Pattern Matching for instanceof (Second Preview)
377 ZGC: A Scalable Low-Latency Garbage Collector
378 Text Blocks
379 Shenandoah: A Low-Pause-Time Garbage Collector
381 Remove the Solaris and SPARC Ports
383 Foreign-Memory Access API (Second Incubator)
384 Records (Second Preview)
385 Deprecate RMI Activation for Removal
13. 廃⽌や削除
Removed or deprecated
339 Edwards-Curve Digital Signature Algorithm (EdDSA)
360 Sealed Classes (Preview)
371 Hidden Classes
372 Remove the Nashorn JavaScript Engine
373 Reimplement the Legacy DatagramSocket API
374 Disable and Deprecate Biased Locking
375 Pattern Matching for instanceof (Second Preview)
377 ZGC: A Scalable Low-Latency Garbage Collector
378 Text Blocks
379 Shenandoah: A Low-Pause-Time Garbage Collector
381 Remove the Solaris and SPARC Ports
383 Foreign-Memory Access API (Second Incubator)
384 Records (Second Preview)
385 Deprecate RMI Activation for Removal
14. 新機能や追加機能
New or additional features
339 Edwards-Curve Digital Signature Algorithm (EdDSA)
360 Sealed Classes (Preview)
371 Hidden Classes
372 Remove the Nashorn JavaScript Engine
373 Reimplement the Legacy DatagramSocket API
374 Disable and Deprecate Biased Locking
375 Pattern Matching for instanceof (Second Preview)
377 ZGC: A Scalable Low-Latency Garbage Collector
378 Text Blocks
379 Shenandoah: A Low-Pause-Time Garbage Collector
381 Remove the Solaris and SPARC Ports
383 Foreign-Memory Access API (Second Incubator)
384 Records (Second Preview)
385 Deprecate RMI Activation for Removal
15. プレビューもしくはインキュベート機能
Preview or incubator projects
339 Edwards-Curve Digital Signature Algorithm (EdDSA)
360 Sealed Classes (Preview)
371 Hidden Classes
372 Remove the Nashorn JavaScript Engine
373 Reimplement the Legacy DatagramSocket API
374 Disable and Deprecate Biased Locking
375 Pattern Matching for instanceof (Second Preview)
377 ZGC: A Scalable Low-Latency Garbage Collector
378 Text Blocks
379 Shenandoah: A Low-Pause-Time Garbage Collector
381 Remove the Solaris and SPARC Ports
383 Foreign-Memory Access API (Second Incubator)
384 Records (Second Preview)
385 Deprecate RMI Activation for Removal
29. 新機能や追加機能
New or additional features
339 Edwards-Curve Digital Signature Algorithm (EdDSA)
360 Sealed Classes (Preview)
371 Hidden Classes
372 Remove the Nashorn JavaScript Engine
373 Reimplement the Legacy DatagramSocket API
374 Disable and Deprecate Biased Locking
375 Pattern Matching for instanceof (Second Preview)
377 ZGC: A Scalable Low-Latency Garbage Collector
378 Text Blocks
379 Shenandoah: A Low-Pause-Time Garbage Collector
381 Remove the Solaris and SPARC Ports
383 Foreign-Memory Access API (Second Incubator)
384 Records (Second Preview)
385 Deprecate RMI Activation for Removal
33. Fooというクラスにbarというメソッドがあるとして...
When Class 'Foo' has a method named 'bar'...
// Class is stored in byte array
byte[] bytes = Files.readAllBytes(Paths.get("Foo.class"));
MethodHandles.Lookup lookup = MethodHandles.lookup();
// Look up the hidden class
lookup.defineHiddenClass(bytes, false);
Class<?> clazz = lookup.findClass("Foo");
Constructor constuctor = clazz.getDeclaredConstructor();
Object hiddenClassInstance = constuctor.newInstance();
// Get method declared in the hidden class and invoke it
Method method = clazz.getDeclaredMethod("bar");
method.invoke(hiddenClassInstance);
34. 注意点
java.lang.Error: thrown from hidden class com.example.Foo/0x0000000800b7a470
at m1/com.example.Foo/0x0000000800b7a470.toString(Foo.java:16)
at m1/com.example.Foo_0x0000000800b7a470$$Lambda$29/0x0000000800b7c040.apply(<Unknown>:1000001)
at m1/com.example.Foo/0x0000000800b7a470.test(Foo.java:11)
50. Pattern
openjdk.java.net/jeps/375
ž A pattern is a combination of (1) a predicate that can be applied to a
target, and (2) a set of binding variables that are extracted from the
target only if the predicate successfully applies to it.
ž A type test pattern consists of a predicate that specifies a type,
along with a single binding variable.
obj instanceof String s
(1) (2)
型テストパターン (type test pattern)
56. public final class Point extends Record {
private final int x;
private final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int x() {
return x;
}
public int y() {
return y;
}
public int hashCode() { ... }
public boolean equals() { ... }
public String toString() { ... }
}
フィールドの名前がそのままAPI
(getXXXではない)
メンバーはfinal
setter (setXXX) は存在しない
58. public record Point(int x, int y) {}
...
Point p1 = new Point(1, 2);
Point p2 = new Point(1, 2);
Point p3 = new Point(p1.x(), p1.y());
Point p4 = new Point(p1.x(), p2.y());
boolean b1_2 = p1.equals(p2); // true
boolean b1_3 = p1.equals(p3); // true
boolean b3_4 = p3.equals(p4); // true
...
63. Recordと組み合わせることもできる
Able to use Sealed type along with Records
Public sealed interface Expr
permits ConstantExpr, PlusExpr, TimesExpr, NegExpr {...}
public record ConstantExpr(int i) implements Expr {...}
public record PlusExpr(Expr a, Expr b) implements Expr {...}
public record TimesExpr(Expr a, Expr b) implements Expr {...}
public record NegExpr(Expr e) implements Expr {...}
64. instanceof を使ったパターンマッチング
Pattern matching with instanceof
public sealed class Shape
permits Circle, Rectangle, Square {...}
final class Circle extends Shape {...}
final class Rectangle extends Shape {...}
final class Square extends Shape {...}
Shape rotate(Shape shape, double angle) {
return switch (shape) {
case Circle c -> c; // no-op
case Rectangle r -> r.rotate(angle);
case Square s -> s.rotate(angle);
}
}
73. VarHandle を使ってセグメント内のメモリにアクセス
Dereference memory segment using VarHandle
// Get a VarHandle for int type
VarHandle intHandle = MemoryHandles.varHandle( int.class,
ByteOrder.nativeOrder());
// Allocate a memory segment (100 bytes), and access it
try (MemorySegment segment = MemorySegment.allocateNative(100)) {
MemoryAddress base = segment.baseAddress();
for (int i = 0; i < 25; i++) {
// Access foreign memory with int type VarHandle
intHandle.set(base.addOffset(i * 4), i);
}
}
74. セグメントのオーナーシップ – Serial confinement
Segment ownership – Serial confinement
// If segmentA is created in threadA, the segment is confined by threadA
MemorySegment segmentA = ...;
...
// confined by thread B
var segmentB = segmentA.withOwnerThread(threadB);
// shared segment – any threads can access this memory segment.
var segmentB = segmentA.withOwnerThread(null);
75. セグメントのオーナーシップ - Parallel confinement
Segment ownership - Parallel confinement
// create a memory segment whose size is 1,000,000 × JAVA_INT
SequenceLayout seq = MemoryLayout.ofSequence(1_000_000, MemoryLayouts.JAVA_INT);
SequenceLayout seq_bulk = seq.reshape(-1, 100);
VarHandle intHandle = seq.varHandle(int.class, PathElement.sequenceElement());
// Using spliterator to process memory contents in parallel
int sum = StreamSupport.stream(MemorySegment.spliterator(segment, seq_bulk), true)
.mapToInt(slice -> {
int res = 0;
MemoryAddress base = slice.baseAddress();
for (int i = 0; i < 100 ; i++) {
res += (int)intHandle.get(base, (long)i);
}
return res;
}).sum();