Skip to content

Commit d22a250

Browse files
authored
Update JDK features (24/25 & more) (#75)
* Add test classes and features for Java 24 and 25 - includes samples for standard features only - adds markdown javadoc for JEPs - organizes classes related to Java 24 and 25 - introduces `CompactSourceFile` and `JavaBaseImport` classes * Update test classes for Java 4, 5, 12, and 15 - add new test cases for Collections API, formatted string handling, JavaBeans EventHandler, and NIO features - improve code documentation and readability
1 parent dadbe57 commit d22a250

File tree

8 files changed

+157
-3
lines changed

8 files changed

+157
-3
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/// Is a final top-level class in the unnamed package;
2+
/// Extends java.lang.Object and does not implement any interfaces;
3+
/// Has a default constructor with no parameters, and no other constructors;
4+
/// Has, as its members, the fields and methods in the compact source file; and
5+
/// Must have a launchable main method; if it does not, a compile-time error is reported.
6+
void main() {
7+
IO.println("Compact source file & main method here ...");
8+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package pl.mperor.lab.java;
2+
3+
import module java.base;
4+
5+
class JavaBaseImport {
6+
7+
private final List<String> listFromUtilPackage = List.of("a", "b", "c");
8+
private final File fileFromIoPackage = new File("file.txt");
9+
10+
}

JavaReleases/src/test/java/pl/mperor/lab/java/Java12.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ private String generateFileHashMD5(Path file) throws NoSuchAlgorithmException, I
6262

6363
StringBuilder sb = new StringBuilder();
6464
for (byte b : hashBytes) {
65-
sb.append(String.format("%02x", b));
65+
sb.append(String.format("%02x", b)); // byte to 2‑digit hex
6666
}
6767
return sb.toString();
6868
}

JavaReleases/src/test/java/pl/mperor/lab/java/Java15.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,15 @@ public void testTextBlock() {
6262

6363
@Test
6464
public void testStringFormatted() {
65-
Assertions.assertEquals("Hello World!", "Hello %s".formatted("World!"));
65+
var positionInFormatted = """
66+
user: %1$s
67+
last name: %2$s
68+
name: %1$s""".formatted("John", "Smith");
69+
Assertions.assertEquals("""
70+
user: John
71+
last name: Smith
72+
name: John""", positionInFormatted);
73+
6674
Assertions.assertEquals("Value: 0.00", String.format(Locale.US, "Value: %.2f", 0d));
6775
}
6876

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
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.util.List;
7+
import java.util.stream.Gatherers;
8+
import java.util.stream.IntStream;
9+
10+
/// Java 24 (March 2025)
11+
/// [JDK 24](https://openjdk.org/projects/jdk/24)
12+
///
13+
/// - STANDARD FEATURES:
14+
/// - 472: Prepare to Restrict the Use of JNI
15+
/// - 475: Late Barrier Expansion for G1
16+
/// - 479: Remove the Windows 32-bit x86 Port
17+
/// - 483: Ahead-of-Time Class Loading & Linking
18+
/// - 484: Class-File API
19+
/// - 485: Stream Gatherers
20+
/// - 486: Permanently Disable the Security Manager
21+
/// - 490: ZGC: Remove the Non-Generational Mode
22+
/// - 491: Synchronize Virtual Threads without Pinning
23+
/// - 493: Linking Run-Time Images without JMODs
24+
/// - 496: Quantum-Resistant Module-Lattice-Based Key Encapsulation Mechanism
25+
/// - 497: Quantum-Resistant Module-Lattice-Based Digital Signature Algorithm
26+
/// - 498: Warn upon Use of Memory-Access Methods in sun.misc.Unsafe
27+
/// - 501: Deprecate the 32-bit x86 Port for Removal
28+
///
29+
/// - PREVIEW & INCUBATOR:
30+
/// - 404: Generational Shenandoah (Experimental)
31+
/// - 450: Compact Object Headers (Experimental)
32+
/// - 478: Key Derivation Function API (Preview)
33+
/// - 487: Scoped Values (Fourth Preview)
34+
/// - 488: Primitive Types in Patterns, instanceof, and switch (Second Preview)
35+
/// - 489: Vector API (Ninth Incubator)
36+
/// - 492: Flexible Constructor Bodies (Third Preview)
37+
/// - 494: Module Import Declarations (Second Preview)
38+
/// - 495: Simple Source Files and Instance Main Methods (Fourth Preview)
39+
public class Java24 {
40+
41+
@Test
42+
public void testWindowFixedGatherer() {
43+
var result = IntStream.rangeClosed(1, 3)
44+
.boxed()
45+
.gather(Gatherers.windowFixed(2))
46+
.toList();
47+
48+
Assertions.assertEquals(
49+
List.of(
50+
List.of(1, 2),
51+
List.of(3)
52+
), result);
53+
}
54+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package pl.mperor.lab.java;
2+
3+
import org.junit.jupiter.api.Assertions;
4+
import org.junit.jupiter.api.Test;
5+
import pl.mperor.lab.common.TestUtils;
6+
7+
/// Java 25 (September 2025)
8+
/// [JDK 25](https://openjdk.org/projects/jdk/25)
9+
///
10+
/// - STANDARD FEATURES:
11+
/// - 503: Remove the 32-bit x86 Port
12+
/// - 506: Scoped Values
13+
/// - 510: Key Derivation Function API
14+
/// - 511: Module Import Declarations
15+
/// - 512: Compact Source Files and Instance Main Methods
16+
/// - 513: Flexible Constructor Bodies
17+
/// - 514: Ahead-of-Time Command-Line Ergonomics
18+
/// - 515: Ahead-of-Time Method Profiling
19+
/// - 518: JFR Cooperative Sampling
20+
/// - 519: Compact Object Headers
21+
/// - 520: JFR Method Timing & Tracing
22+
/// - 521: Generational Shenandoah
23+
///
24+
/// - PREVIEW & INCUBATOR:
25+
/// - 470: PEM Encodings of Cryptographic Objects (Preview)
26+
/// - 502: Stable Values (Preview)
27+
/// - 505: Structured Concurrency (Fifth Preview)
28+
/// - 507: Primitive Types in Patterns, instanceof, and switch (Third Preview)
29+
/// - 508: Vector API (Tenth Incubator)
30+
/// - 509: JFR CPU-Time Profiling (Experimental)
31+
public class Java25 {
32+
33+
@Test
34+
public void testPrintFromIOClass() {
35+
var out = TestUtils.setTempSystemOut();
36+
IO.println("Hello World!"); // ⇒ System.out.println("Hello World!");
37+
Assertions.assertEquals("Hello World!" + System.lineSeparator(), out.all());
38+
TestUtils.resetSystemOut();
39+
}
40+
41+
}

JavaReleases/src/test/java/pl/mperor/lab/java/Java4.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,21 @@
22

33
import org.junit.jupiter.api.Assertions;
44
import org.junit.jupiter.api.Test;
5+
import pl.mperor.lab.common.TestUtils;
56

67
import javax.imageio.ImageIO;
78
import java.awt.image.BufferedImage;
9+
import java.beans.EventHandler;
810
import java.io.*;
911
import java.net.InetSocketAddress;
1012
import java.net.ServerSocket;
1113
import java.nio.channels.ServerSocketChannel;
1214
import java.nio.channels.SocketChannel;
1315
import java.nio.file.Files;
1416
import java.nio.file.Path;
17+
import java.nio.file.attribute.BasicFileAttributes;
18+
import java.nio.file.attribute.FileTime;
19+
import java.time.Instant;
1520
import java.util.concurrent.CountDownLatch;
1621
import java.util.concurrent.Executors;
1722
import java.util.logging.Logger;
@@ -37,8 +42,12 @@ public void testNewInputOutputAkaNIO() throws IOException {
3742
Path path = Path.of("src", "test", "resources", "nio.txt");
3843
byte[] fileBytes = Files.readAllBytes(path);
3944
String content = new String(fileBytes);
40-
4145
Assertions.assertEquals("Hello NIO!", content);
46+
47+
var fileCreationTime = Files.readAttributes(path, BasicFileAttributes.class)
48+
.creationTime();
49+
System.out.printf("📃 File '%s' - last access time: ⌚%s%n: ", path.getFileName(), fileCreationTime);
50+
Assertions.assertTrue(fileCreationTime.compareTo(FileTime.from(Instant.now())) <= 0);
4251
}
4352

4453
@Test
@@ -125,4 +134,17 @@ private void handleConnectedClient(ServerSocket serverSocket) throws IOException
125134
}
126135
}
127136

137+
@Test
138+
public void testJavaBeansEventHandler() {
139+
var out = TestUtils.setTempSystemOut();
140+
Runnable runnable = EventHandler.create(Runnable.class, this, "run"); // () -> run();
141+
runnable.run();
142+
Assertions.assertEquals("Run was called!", out.all());
143+
TestUtils.resetSystemOut();
144+
}
145+
146+
public void run() {
147+
System.out.print("Run was called!");
148+
}
149+
128150
}

JavaReleases/src/test/java/pl/mperor/lab/java/Java5.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import java.lang.annotation.*;
99
import java.lang.reflect.Method;
1010
import java.util.Arrays;
11+
import java.util.Collections;
1112
import java.util.List;
1213
import java.util.concurrent.*;
1314
import java.util.concurrent.atomic.AtomicInteger;
@@ -146,4 +147,14 @@ public void testStringBuilderInsteadOfStringBuffer() {
146147
Assertions.assertEquals("Hello World", sb.reverse().toString());
147148
}
148149

150+
@Test
151+
public void testCollectionsAPI() {
152+
var collection = List.of(1,2,3,2,2);
153+
Assertions.assertEquals(3, Collections.frequency(collection, 2));
154+
155+
List<String> empty = Collections.emptyList();
156+
Assertions.assertNotNull(empty);
157+
Assertions.assertTrue(empty.isEmpty());
158+
}
159+
149160
}

0 commit comments

Comments
 (0)