Skip to content

Java 18

Neelu edited this page Jul 26, 2026 · 1 revision

☕ Java 18: UTF-8 by Default & Simple Web Server

Release Date: March 22, 2022 | Type: Standard (non-LTS) | Status: ⚠️ End of Life


📋 Table of Contents

  1. Overview
  2. Core Features
  3. Best Practices

🎯 Overview

Java 18 is a quieter release focused on consistency and developer convenience: UTF-8 finally becomes the guaranteed default charset everywhere, and a built-in HTTP server ships for quick testing needs.

flowchart LR
    A["Platform-dependent\ndefault charset\n(Windows: Cp1252, Linux: UTF-8)"] -->|JEP 400| B["UTF-8 everywhere,\nevery platform"]
Loading

🚀 Core Features

1️⃣ UTF-8 by Default (JEP 400)

What: Charset.defaultCharset() now returns UTF-8 unconditionally, regardless of OS/locale settings.

// Before Java 18: this could silently return different encodings
// depending on the OS locale — a classic source of "works on my machine" bugs
System.out.println(Charset.defaultCharset()); // now always UTF-8

// APIs that were previously platform-dependent are now consistent:
new String(bytes);                    // uses UTF-8
new FileReader("file.txt");           // uses UTF-8
System.out.println("data");           // System.out now defaults to UTF-8

Why it matters: This single change quietly fixed a whole category of bugs where a file written correctly on Linux (UTF-8 default) would read incorrectly on Windows (which defaulted to Cp1252 or similar) — extremely common in CI/CD pipelines mixing OS types.

flowchart TD
    A[File written on Linux CI] -->|UTF-8| B[Committed to repo]
    B --> C{Read on Windows dev machine}
    C -->|Before Java 18: Cp1252 default| D["❌ Mojibake / corrupted text"]
    C -->|Java 18+: UTF-8 default| E["✅ Reads correctly everywhere"]
Loading

2️⃣ Simple Web Server (JEP 408)

What: A minimal, static-file HTTP server — zero dependencies, one command. Perfect for quick local testing, prototyping, or serving docs.

# Serve the current directory on port 8000
jwebserver

# Custom port and directory
jwebserver -p 9000 -d /path/to/static/files

# Bind to a specific address
jwebserver -b 127.0.0.1 -p 8080

Programmatic API:

import com.sun.net.httpserver.*;
import java.net.InetSocketAddress;

var server = SimpleFileServer.createFileServer(
    new InetSocketAddress(8080),
    Path.of("/path/to/static"),
    SimpleFileServer.OutputLevel.VERBOSE
);
server.start();

Why it matters: No more python -m http.server or spinning up a full servlet container just to eyeball a static export or test a webhook receiver locally.


3️⃣ Code Snippets in JavaDoc (JEP 413)

What: A cleaner @snippet tag replacing awkward <pre>{@code ...}</pre> blocks in Javadoc, with external file support.

/**
 * Calculates the discount for a given order.
 *
 * Example usage:
 * {@snippet :
 *     Order order = new Order(100.0);
 *     double discount = calculateDiscount(order);
 *     System.out.println(discount); // 10.0
 * }
 */
public static double calculateDiscount(Order order) {
    return order.total() * 0.10;
}
// Or reference an external, compiled-and-tested example file:
/**
 * {@snippet file="DiscountExample.java" region="example"}
 */

4️⃣ Vector API (3rd Incubator) & FFM API (2nd Incubator)

Both continue maturing — see the Java 16 guide for Vector API basics and the Java 22 guide for the standardized Foreign Function & Memory API.


5️⃣ Deprecate Finalization for Removal

// Object.finalize() is now formally on the path to removal (gone by Java 24 as a no-op-eligible warning path)
@Override
protected void finalize() { // ⚠️ compiler/runtime warns — migrate to Cleaner or try-with-resources
    // ...
}

// Use java.lang.ref.Cleaner instead
public class Resource implements AutoCloseable {
    private static final Cleaner cleaner = Cleaner.create();
    private final Cleaner.Cleanable cleanable;

    public Resource() {
        this.cleanable = cleaner.register(this, () -> System.out.println("cleaned up"));
    }

    @Override
    public void close() {
        cleanable.clean();
    }
}

💡 Best Practices

✅ Stop manually specifying StandardCharsets.UTF_8 everywhere defensively — it's now the safe default (though being explicit still documents intent)
✅ Use jwebserver for quick local static-file testing instead of installing extra tooling
✅ Migrate any finalize() usage to try-with-resources + AutoCloseable, or java.lang.ref.Cleaner
❌ Don't use the Simple Web Server for production — it's intentionally minimal (no HTTPS, no dynamic content, static files only)


Clone this wiki locally