1+ package pl .mperor .lab .java ;
2+
3+ import org .junit .jupiter .api .Assertions ;
4+ import org .junit .jupiter .api .Test ;
5+
6+ import java .lang .foreign .*;
7+ import java .lang .invoke .MethodHandle ;
8+ import java .text .ListFormat ;
9+ import java .util .Comparator ;
10+ import java .util .List ;
11+ import java .util .Locale ;
12+ import java .util .function .Supplier ;
13+ import java .util .stream .Collectors ;
14+ import java .util .stream .IntStream ;
15+ import java .util .stream .Stream ;
16+
17+ /// Java 22 (March 2024)
18+ /// [JDK 22](https://openjdk.org/projects/jdk/22)
19+ ///
20+ /// - STANDARD FEATURES:
21+ /// - 454: Foreign Function & Memory API
22+ /// - 456: Unnamed Variables & Patterns
23+ /// - 458: Launch Multi-File Source-Code Programs
24+ /// - 423: Region Pinning for G1
25+ ///
26+ /// - PREVIEW & INCUBATOR:
27+ /// - 461: Stream Gatherers (Preview)
28+ /// - 457: Class-File API (Preview)
29+ /// - 447: Statements before super(...) (Preview)
30+ /// - 459: String Templates (Second Preview)
31+ /// - 462: Structured Concurrency (Second Preview)
32+ /// - 463: Implicitly Declared Classes and Instance Main Methods (Second Preview)
33+ /// - 464: Scoped Values (Second Preview)
34+ /// - 460: Vector API (Seventh Incubator)
35+ public class Java22 {
36+
37+ @ Test
38+ public void testForeignFunction () throws Throwable {
39+ String str = "test" ;
40+ Arena arena = Arena .ofAuto ();
41+ MemorySegment cString = arena .allocateFrom (str );
42+ Linker linker = Linker .nativeLinker ();
43+ SymbolLookup stdlib = linker .defaultLookup ();
44+ MethodHandle strlen = linker .downcallHandle (
45+ stdlib .find ("strlen" ).orElseThrow (),
46+ FunctionDescriptor .of (ValueLayout .JAVA_LONG , ValueLayout .ADDRESS )
47+ );
48+ Assertions .assertEquals ((long ) str .length (), strlen .invoke (cString ));
49+ }
50+
51+ @ Test
52+ public void testMemoryAPI () {
53+ var intArrayLayout = MemoryLayout .sequenceLayout (10 , ValueLayout .JAVA_INT );
54+ try (var arena = Arena .ofConfined ()) {
55+ var segment = arena .allocate (intArrayLayout );
56+ for (int i = 0 ; i < intArrayLayout .elementCount (); i ++) {
57+ segment .setAtIndex (ValueLayout .JAVA_INT , i , i );
58+ Assertions .assertEquals (i , segment .getAtIndex (ValueLayout .JAVA_INT , i ));
59+ }
60+ }
61+ }
62+
63+ @ Test
64+ public void testUnnamedVariables () {
65+ String repeated = IntStream .rangeClosed (1 , 3 )
66+ .mapToObj (_ -> "Java 23!" )
67+ .collect (Collectors .joining ());
68+ Assertions .assertEquals ("Java 23!" .repeat (3 ), repeated );
69+
70+ Comparator <Integer > uselessComparator = (_ , _ ) -> 1 ;
71+ int [] sorted = Stream .of (1 , 2 , 3 )
72+ .sorted (uselessComparator )
73+ .mapToInt (Integer ::intValue )
74+ .toArray ();
75+ Assertions .assertArrayEquals (new int []{1 , 2 , 3 }, sorted );
76+
77+ Assertions .assertDoesNotThrow (() -> muteException (() -> 1 / 0 ));
78+ Assertions .assertDoesNotThrow (() -> muteException (() -> null ));
79+ Assertions .assertDoesNotThrow (() -> muteException (() -> {
80+ throw new NullPointerException ();
81+ }));
82+ }
83+
84+ private static <T > T muteException (Supplier <T > supplier ) {
85+ try {
86+ return supplier .get ();
87+ } catch (Exception _) {
88+ return null ;
89+ }
90+ }
91+
92+ @ Test
93+ public void testUnnamedPatterns () {
94+ Assertions .assertTrue (readyToGo (new GreenLight ()));
95+ Assertions .assertTrue (readyToGo (new YellowLight ()));
96+ Assertions .assertFalse (readyToGo (new RedLight ()));
97+ }
98+
99+ public boolean readyToGo (TrafficLight light ) {
100+ return switch (light ) {
101+ case GreenLight _ , YellowLight _ -> true ;
102+ case RedLight _ -> false ;
103+ };
104+ }
105+
106+ sealed abstract class TrafficLight permits RedLight , YellowLight , GreenLight {}
107+
108+ final class RedLight extends TrafficLight {}
109+
110+ final class YellowLight extends TrafficLight {}
111+
112+ final class GreenLight extends TrafficLight {}
113+
114+ @ Test
115+ public void testForbiddenForUnnamed () {
116+ var unnamed = new Unnamed ();
117+ Assertions .assertEquals ("this is ok!" , unnamed .__ );
118+ Assertions .assertDoesNotThrow (() -> unnamed .works (0 ));
119+ }
120+
121+ private static class Unnamed {
122+ //private String _ = "this is forbidden!";
123+
124+ private String __ = "this is ok!" ;
125+
126+ //private void forbidden(int _) {
127+ //}
128+ private void works (int __ ) {
129+ }
130+ }
131+
132+ @ Test
133+ public void testSystemEncodingProperties () {
134+ Assertions .assertNotNull (System .getProperty ("stdout.encoding" ));
135+ Assertions .assertNotNull (System .getProperty ("stderr.encoding" ));
136+ }
137+
138+ @ Test
139+ public void testListFormat () {
140+ String formatted = ListFormat .getInstance (Locale .UK , ListFormat .Type .STANDARD , ListFormat .Style .FULL )
141+ .format (List .of ("One" , "Two" , "Three" ));
142+ Assertions .assertEquals ("One, Two and Three" , formatted );
143+ }
144+ }
0 commit comments