Add jep512 module: compact source files and instance main methods on JDK 25 and 27
Runnable sources, broken examples and captured transcripts for the ankurm.com JEP 512 article, including the measured launch order and a private-constructor difference between 25 and 27. Co-Authored-By: Claude Sonnet 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01TF9JWFvJSNm6HVzswzZU5a
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
// The same program the way every tutorial before Java 25 wrote it, for the side-by-side in the post.
|
||||
public class Classic {
|
||||
public static void main(String[] args) {
|
||||
System.out.println("Hello, world");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
// The smallest complete Java 25 program. No class, no public, no static, no String[] args.
|
||||
void main() {
|
||||
IO.println("Hello, world");
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// Instance main does not need a compact file. An ordinary class works too, and then it can use its own fields.
|
||||
class InstanceMainInClass {
|
||||
private final String greeting = "hello from an instance field";
|
||||
|
||||
void main() {
|
||||
IO.println(greeting);
|
||||
IO.println("this class is " + getClass().getName() + ", final? " + java.lang.reflect.Modifier.isFinal(getClass().getModifiers()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// IO lives in java.lang, so IO.println needs no import in an ordinary class either.
|
||||
public class IoInAnyClass {
|
||||
public static void main(String[] args) {
|
||||
IO.println("IO.println works in a normal class with no import");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// A compact source file is a whole class body: fields, methods, and nested types all sit at the top level.
|
||||
// Nothing here is imported. List, Map, TreeMap, Collectors and BigDecimal all live in java.base.
|
||||
String greeting = "hello";
|
||||
int calls = 0;
|
||||
|
||||
record Point(int x, int y) {
|
||||
double distance() { return Math.sqrt(x * x + y * y); }
|
||||
}
|
||||
|
||||
String shout(String s) {
|
||||
calls++;
|
||||
return s.toUpperCase() + "!";
|
||||
}
|
||||
|
||||
void main() {
|
||||
List<String> words = List.of("banana", "apple", "cherry");
|
||||
Map<String, Integer> lengths = new TreeMap<>();
|
||||
for (String w : words) lengths.put(w, w.length());
|
||||
IO.println(shout(greeting));
|
||||
IO.println(words.stream().sorted().collect(Collectors.joining(", ")));
|
||||
IO.println(lengths);
|
||||
IO.println(new BigDecimal("1.10").add(BigDecimal.ONE));
|
||||
IO.println(new Point(3, 4) + " is " + new Point(3, 4).distance() + " from the origin");
|
||||
IO.println("calls so far: " + calls);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// java.net.http is a separate module from java.base, so HttpClient is NOT implicitly imported.
|
||||
// A normal single-type import fixes it, exactly as in any other Java file.
|
||||
import java.net.http.HttpClient;
|
||||
|
||||
void main() {
|
||||
HttpClient client = HttpClient.newHttpClient();
|
||||
IO.println("default HTTP version: " + client.version());
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
// The other fix: import the whole module (JEP 511, final in Java 25). One line covers java.net.http.
|
||||
import module java.net.http;
|
||||
|
||||
void main() {
|
||||
HttpClient client = HttpClient.newHttpClient();
|
||||
IO.println("default HTTP version: " + client.version());
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
// java.lang.IO has three static methods: print, println and readln.
|
||||
void main() {
|
||||
String name = IO.readln("Your name? ");
|
||||
String age = IO.readln("Your age? ");
|
||||
IO.println("Hello " + name + ", " + age + " is a good age to learn Java.");
|
||||
IO.print("no newline after this, ");
|
||||
IO.println("newline after this");
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// What did the compiler make of a compact source file? Ask the class itself.
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class Reflect {
|
||||
public static void main(String[] args) throws Exception {
|
||||
Class<?> c = Class.forName("Hello");
|
||||
IO.println("name : " + c.getName());
|
||||
IO.println("final : " + Modifier.isFinal(c.getModifiers()));
|
||||
IO.println("public : " + Modifier.isPublic(c.getModifiers()));
|
||||
IO.println("package : '" + c.getPackageName() + "' (unnamed)");
|
||||
IO.println("superclass : " + c.getSuperclass().getName());
|
||||
IO.println("declared : " + Arrays.stream(c.getDeclaredMethods()).map(m -> m.toString()).sorted().toList());
|
||||
IO.println("constructors: " + Arrays.toString(c.getDeclaredConstructors()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// The bare println form works only if you import IO's static methods yourself.
|
||||
import static java.lang.IO.*;
|
||||
|
||||
void main() {
|
||||
println("println without the IO. prefix, after import static java.lang.IO.*");
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// The String[] parameter is still allowed; it is just no longer required.
|
||||
void main(String[] args) {
|
||||
IO.println("args.length = " + args.length);
|
||||
for (String a : args) IO.println(" arg: " + a);
|
||||
}
|
||||
Reference in New Issue
Block a user