33import org .junit .jupiter .api .Assertions ;
44import org .junit .jupiter .api .Disabled ;
55import org .junit .jupiter .api .Test ;
6+ import org .junit .jupiter .api .condition .EnabledOnOs ;
7+ import org .junit .jupiter .api .condition .OS ;
68import pl .mperor .lab .TestUtils ;
79
810import java .io .IOException ;
11+ import java .net .StandardProtocolFamily ;
12+ import java .net .UnixDomainSocketAddress ;
13+ import java .nio .channels .ServerSocketChannel ;
14+ import java .nio .file .Files ;
15+ import java .nio .file .Path ;
16+ import java .nio .file .Paths ;
917import java .time .LocalTime ;
1018import java .time .format .DateTimeFormatter ;
1119import java .util .List ;
1220import java .util .Locale ;
21+ import java .util .Objects ;
1322import java .util .stream .Collectors ;
1423
15- /**
16- * Java 16 (March 2021)
17- */
24+ /// Java 16™ (March 2021)
25+ /// [JDK 16](https://openjdk.org/projects/jdk/16)
26+ ///
27+ /// - STANDARD FEATURES:
28+ /// - 395: Records
29+ /// - 394: Pattern Matching for instanceof
30+ /// - 390: Warnings for Value-Based Classes
31+ /// - 392: Packaging Tool
32+ /// - 396: Strongly Encapsulate JDK Internals by Default
33+ /// - 376: ZGC: Concurrent Thread-Stack Processing
34+ /// - 380: Unix-Domain Socket Channels
35+ /// - 387: Elastic Metaspace
36+ /// - 347: Enable C++14 Language Features
37+ /// - 386: Alpine Linux Port
38+ /// - 388: Windows/AArch64 Port
39+ /// - 357: Migrate from Mercurial to Git
40+ /// - 369: Migrate to GitHub
41+ ///
42+ /// - PREVIEW & INCUBATOR:
43+ /// - 389: Foreign Linker API (Incubator)
44+ /// - 397: Sealed Classes (Second Preview)
45+ /// - 393: Foreign-Memory Access API (Third Incubator)
46+ /// - 338: Vector API (Incubator)
1847public class Java16 {
1948
49+ // POJOs
50+ @ Test
51+ public void testPairRecord () {
52+ var pair = Pair .of ("Boy" , "Girl" );
53+ Assertions .assertEquals ("Boy" , pair .left );
54+ Assertions .assertEquals ("Girl" , pair .right );
55+ Assertions .assertEquals ("Pair[left=Boy, right=Girl]" , pair .toString ());
56+ Assertions .assertEquals (Pair .of (1 , 1 ), Pair .of (1 , 1 ));
57+ Assertions .assertNotEquals (Pair .of (0 , 0 ), Pair .of (1 , 1 ));
58+ Assertions .assertThrows (NullPointerException .class , () -> Pair .of (0 , null ));
59+ }
60+
61+ record Pair <L , R >(L left , R right ) {
62+ Pair {
63+ Objects .requireNonNull (left );
64+ Objects .requireNonNull (right );
65+ }
66+
67+ public static <L , R > Pair <L , R > of (L left , R right ) {
68+ return new Pair <>(left , right );
69+ }
70+ }
71+
72+ @ Test
73+ public void testPatternMatchingInstanceOfAkaSmartCasting () {
74+ Object o = "Hello String!" ;
75+ if (o instanceof String s ) {
76+ Assertions .assertNotNull (s );
77+ Assertions .assertInstanceOf (String .class , s );
78+ }
79+ Assertions .assertTrue (nonEmptyString ("Hello World!" ));
80+ Assertions .assertFalse (nonEmptyString (null ));
81+ }
82+
83+ private static boolean nonEmptyString (Object obj ) {
84+ return (obj instanceof String str ) && !str .isEmpty ();
85+ }
86+
87+ @ SuppressWarnings ({"removal" , "synchronization" })
88+ @ Test
89+ public void testValueBasedClasses () {
90+ // warning: [removal] Long(long) in Long has been deprecated and marked for removal
91+ Long longByConstructor = new Long (13 );
92+
93+ // warning: [synchronization] attempt to synchronize on an instance of a value-based class
94+ synchronized (longByConstructor ) {
95+ System .out .println ("From the synchronized block!" );
96+ }
97+
98+ Long longByFactoryMethod = Long .valueOf (13L );
99+ Assertions .assertFalse (longByConstructor == longByFactoryMethod );
100+ Assertions .assertTrue (longByConstructor .equals (longByFactoryMethod ));
101+ Assertions .assertTrue (Long .valueOf (13L ) == longByFactoryMethod );
102+ }
103+
20104 @ Test
21105 public void testPeriodSupport () {
22106 LocalTime date = LocalTime .parse ("16:00:00" );
@@ -70,23 +154,6 @@ public void call() {
70154 TestUtils .resetSystemOut ();
71155 }
72156
73- @ SuppressWarnings ({"removal" , "synchronization" })
74- @ Test
75- public void testValueBasedClasses () {
76- // warning: new Long(...) has been deprecated and marked for removal
77- Long longByConstructor = new Long (13 );
78-
79- // warning: attempt to synchronize on an instance of a value-based class
80- synchronized (longByConstructor ) {
81- System .out .println ("From the synchronized block!" );
82- }
83-
84- Long longByFactoryMethod = Long .valueOf (13L );
85- Assertions .assertFalse (longByConstructor == longByFactoryMethod );
86- Assertions .assertTrue (longByConstructor .equals (longByFactoryMethod ));
87- Assertions .assertTrue (Long .valueOf (13L ) == longByFactoryMethod );
88- }
89-
90157 @ Disabled ("Dependent on the OS and additional libraries, besides having a long execution time." )
91158 @ Test
92159 public void testJPackage () throws IOException , InterruptedException {
@@ -102,4 +169,18 @@ public void testJPackage() throws IOException, InterruptedException {
102169 process .destroy ();
103170 }
104171
172+ @ EnabledOnOs (OS .LINUX )
173+ @ Test
174+ public void testUnixDomainSocketChannels () throws IOException {
175+ Path socketPath = Paths .get ("/tmp/unix_socket" );
176+ Files .deleteIfExists (socketPath );
177+ UnixDomainSocketAddress socketAddress = UnixDomainSocketAddress .of (socketPath );
178+
179+ Assertions .assertNotNull (socketAddress );
180+ Assertions .assertNotNull (StandardProtocolFamily .UNIX );
181+ try (var server = ServerSocketChannel .open (StandardProtocolFamily .UNIX ).bind (socketAddress )) {
182+ Assertions .assertNotNull (server );
183+ }
184+ }
185+
105186}
0 commit comments