Skip to content
Java advanced 3 min read

Java 11 Features

Java 11 (September 2018) was the first Long-Term Support (LTS) release after the move to a six-month cadence, succeeding Java 8 as the default production baseline for years. It’s an incremental but high-value release: quality-of-life additions to String, Files, and collections, a production-grade HttpClient, and ergonomic wins like running a .java file directly. Oracle also removed bundled modules (JavaFX, Java EE, CORBA) here, so it’s a real migration checkpoint, not just a feature drop.

LTS Context

VersionReleasedTypeNotable
82014LTSlambdas, streams, java.time
112018LTSHttpClient, var-in-lambda, String/Files APIs
172021LTSrecords, sealed classes, pattern matching
212023LTSvirtual threads, pattern matching for switch

LTS releases receive years of security and bug fixes. Pick an LTS as your production baseline and treat the interim feature releases as a preview channel.

var in Lambda Parameters

Java 10 added local-variable var; Java 11 extends it to lambda parameters. The sole practical benefit is the ability to attach annotations to an inferred parameter type.

// All three params must use var — you cannot mix var and explicit types.
BiFunction<Integer, Integer, Integer> add = (var a, var b) -> a + b;

list.stream()
    .map((@NonNull var s) -> s.strip())
    .forEach(System.out::println);

New String Methods

"  ".isBlank();          // true  — whitespace-only check
"  hi  ".strip();        // "hi"  — Unicode-aware trim()
"ab".repeat(3);          // "ababab"
"a\nb\nc".lines()        // Stream<String> of lines
    .count();            // 3

strip() improves on trim() by respecting the full Unicode whitespace definition. lines() returns a lazy Stream<String>, ideal for processing large text without splitting into an array.

Files.readString / writeString

Reading and writing an entire text file is now a single call, defaulting to UTF-8.

import java.nio.file.*;

Path p = Path.of("notes.txt");
Files.writeString(p, "first line\nsecond line");
String content = Files.readString(p);
System.out.println(content.lines().count());

Output:

2

The Standardized HttpClient

The java.net.http.HttpClient (incubated in 9/10, finalized in 11) replaces the clunky HttpURLConnection. It supports HTTP/2, WebSocket, and both synchronous and asynchronous calls.

import java.net.http.*;
import java.net.URI;

HttpClient client = HttpClient.newHttpClient();

HttpRequest request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.example.com/status"))
    .header("Accept", "application/json")
    .GET()
    .build();

// Synchronous
HttpResponse<String> resp =
    client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.statusCode());

// Asynchronous
client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
    .thenApply(HttpResponse::body)
    .thenAccept(System.out::println);

The client is immutable and reusable; create one and share it across requests.

Running Single-File Source Code

Java 11 lets you execute a source file directly, with no explicit javac step — perfect for scripts and quick experiments.

java Hello.java

The launcher compiles to memory and runs main in one shot. Combined with a shebang (#!/usr/bin/java --source 11), a .java file becomes an executable script.

Collection.toArray(IntFunction)

A cleaner overload for converting a collection to a typed array, replacing the zero-length-array idiom.

List<String> names = List.of("Ada", "Grace");
String[] arr = names.toArray(String[]::new);   // Java 11
// old: names.toArray(new String[0]);

Feature Summary

FeatureWhy it matters
var in lambdasannotate inferred params
isBlank/strip/repeat/lineseveryday String ergonomics
Files.readString/writeStringone-line file I/O, UTF-8 default
HttpClientmodern HTTP/2 + async, no dependencies
java File.javarun sources without compiling
toArray(IntFunction)type-safe array conversion

Best Practices

  • Standardize on an LTS (11, 17, or 21) for production; reserve interim releases for evaluation.
  • Reuse a single HttpClient instance; it manages a connection pool internally.
  • Prefer strip() over trim() in new code for correct Unicode handling.
  • Use Files.readString/writeString only for files that comfortably fit in memory; stream larger files with Files.lines or BufferedReader.
  • Limit var to cases where the inferred type is obvious from the right-hand side — clarity beats brevity.
Last updated June 1, 2026
Was this helpful?