Java 18

Release Information

  • Release Date: March 22, 2022
  • Support Type: Non-LTS (6-month support)
  • End of Support: September 2022 (superseded by Java 19)
  • JEPs: 9 enhancements

Standard Features

UTF-8 by Default (JEP 400)

UTF-8 is now the default character encoding for Java SE APIs.

Before (Java 17):

// Platform-dependent encoding (Windows: windows-1252, Linux: UTF-8)
String defaultCharset = Charset.defaultCharset().name();
Files.readString(Path.of("file.txt")); // Uses platform default

After (Java 18):

// Always UTF-8 regardless of platform
String defaultCharset = Charset.defaultCharset().name(); // "UTF-8"
Files.readString(Path.of("file.txt")); // Always UTF-8

Impact:

  • Consistency across platforms (Windows, macOS, Linux)
  • Fewer encoding bugs (no more garbled characters from platform mismatch)
  • Breaking change: Code relying on platform default may behave differently

Migration:

// If you need platform-specific encoding
Charset platformCharset = Charset.forName(System.getProperty("native.encoding"));

Simple Web Server (JEP 408)

Command-line HTTP server for prototyping and testing.

Start server:

# Serve current directory on port 8000
jwebserver

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

Access: http://localhost:8000

Programmatic API:

import com.sun.net.httpserver.SimpleFileServer;
import java.net.InetSocketAddress;
import java.nio.file.Path;

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

Use cases:

  • Quick file sharing over local network
  • Testing static websites
  • Serving files for development
  • Educational purposes

Note: Not for production use (no security features, single-threaded)

Code Snippets in Java API Documentation (JEP 413)

@snippet tag for better code examples in JavaDoc.

Before (@code tag):

/**
 * Example:
 * <pre>{@code
 * List<String> list = new ArrayList<>();
 * list.add("Hello");
 * }</pre>
 */

After (@snippet tag):

/**
 * Example:
 * {@snippet :
 * List<String> list = new ArrayList<>();  // @highlight
 * list.add("Hello");
 * list.add("World");  // @link substring=add target="List#add"
 * }
 */

Features:

  • Syntax highlighting markers
  • Links to related documentation
  • Region markers for selective display
  • External files (load snippets from source files)

External snippet example:

/**
 * {@snippet file="examples/HelloWorld.java" region="greeting"}
 */

Preview Features

Pattern Matching for switch (JEP 420) - Second Preview

Improvements:

  • Better exhaustiveness checking
  • Guarded patterns

Example:

static String format(Object obj) {
    return switch (obj) {
        case Integer i -> String.format("int %d", i);
        case Long l -> String.format("long %d", l);
        case Double d -> String.format("double %f", d);
        case String s -> String.format("String %s", s);
        default -> obj.toString();
    };
}

Guarded patterns:

static String classify(int num) {
    return switch (num) {
        case 0 -> "zero";
        case int n when n > 0 -> "positive";
        case int n when n < 0 -> "negative";
    };
}

Incubator Features

Vector API (JEP 417) - Third Incubator

Continued refinement of SIMD operations API.

Performance improvement:

import jdk.incubator.vector.*;

void addArrays(float[] a, float[] b, float[] c) {
    var species = FloatVector.SPECIES_PREFERRED;
    int i = 0;
    for (; i < species.loopBound(a.length); i += species.length()) {
        var va = FloatVector.fromArray(species, a, i);
        var vb = FloatVector.fromArray(species, b, i);
        va.add(vb).intoArray(c, i);
    }
    // Handle remainder
    for (; i < a.length; i++) {
        c[i] = a[i] + b[i];
    }
}

Speedup: 4-8x faster than scalar code

Foreign Function & Memory API (JEP 419) - Second Incubator

Refined API for calling native code and accessing off-heap memory.

Example (calling C strlen):

import java.lang.foreign.*;

Linker linker = Linker.nativeLinker();
SymbolLookup stdlib = linker.defaultLookup();

MethodHandle strlen = linker.downcallHandle(
    stdlib.find("strlen").orElseThrow(),
    FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.ADDRESS)
);

try (Arena arena = Arena.openConfined()) {
    MemorySegment str = arena.allocateUtf8String("Hello");
    long length = (long) strlen.invoke(str);
    System.out.println(length); // 5
}

Other Features

Internet-Address Resolution SPI (JEP 418)

Service Provider Interface for custom hostname resolution.

Use case: Override DNS resolution for testing or special network environments

Example:

public class CustomResolver extends InetAddressResolverProvider {
    @Override
    public InetAddressResolver get(Configuration config) {
        return new InetAddressResolver() {
            @Override
            public Stream<InetAddress> lookupByName(String host, LookupPolicy policy) {
                if (host.equals("test.local")) {
                    return Stream.of(InetAddress.getLoopbackAddress());
                }
                return InetAddressResolver.builtinResolver().lookupByName(host, policy);
            }
        };
    }
}

Reimplement Core Reflection with Method Handles (JEP 416)

Internal improvement - reflection now uses MethodHandles internally.

User impact: Faster reflection performance, smaller footprint

Deprecate Finalization for Removal (JEP 421)

finalize() method deprecated for removal in future release.

Problem with finalization:

  • Unpredictable execution time
  • Performance overhead
  • Resource leak risks
  • Complexity

Alternatives:

// ❌ OLD: finalize()
@Override
protected void finalize() {
    closeResource();
}

// ✅ MODERN: try-with-resources
try (var resource = new MyResource()) {
    resource.use();
}

// ✅ MODERN: Cleaner
Cleaner cleaner = Cleaner.create();
cleaner.register(obj, () -> closeResource());

Migration Considerations

Upgrading from Java 17 LTS:

  1. UTF-8 default: Test applications that read/write files with platform-specific encoding
  2. Finalization: Replace finalize() with try-with-resources or Cleaner
  3. Preview features: Pattern matching for switch requires --enable-preview

Compatibility: Binary compatible with Java 17

Related Topics

References

Sources:

Official OpenJDK JEPs:

Last updated