Standard library
The Java standard library is large. The core packages — java.lang, java.util, java.io, java.nio, java.net, java.time, java.util.concurrent, and the others — cover collections, I/O, networking, time and dates, regular expressions, JSON (since Java 11 in the HTTP client), reflection, threading, cryptography, internationalisation, and a substantial set of utility types. The library is much larger than C++‘s standard library or C’s, and it grows incrementally with each Java revision. This page surveys the principal packages and provides routes to in-depth treatment.
The full standard library is too large to document exhaustively; familiarity with the package structure and the principal classes is part of fluency in the language.
The package structure
The standard library is organised under the java namespace (with a few items under javax and jdk):
| Package | Purpose |
|---|---|
java.lang | Fundamental types; implicitly imported |
java.util | Collections, optionals, dates (legacy), random, regex |
java.util.concurrent | Threading and concurrency utilities |
java.util.function | Functional interfaces |
java.util.stream | Streams API |
java.util.regex | Regular expressions |
java.io | The original I/O (streams, readers, writers) |
java.nio | New I/O (channels, buffers, selectors) |
java.nio.file | Modern filesystem (Path, Files) |
java.net | Networking (URL, Socket, HTTP client) |
java.net.http | HTTP client (since Java 11) |
java.time | Modern date and time |
java.text | Formatting, parsing, internationalisation |
java.security | Cryptography and security |
java.lang.reflect | Reflection |
java.lang.annotation | Annotation infrastructure |
java.sql | JDBC (databases) |
java.lang — fundamental types
Implicitly imported; covers the core types every Java program uses:
| Class | Purpose |
|---|---|
Object | Universal base class |
String, StringBuilder, StringBuffer | Strings |
Integer, Long, Double, Boolean, Character, etc. | Wrapper types |
Math, StrictMath | Math functions |
System | System interaction (System.out, System.err, System.currentTimeMillis) |
Thread, Runnable | Threading |
Throwable, Exception, RuntimeException, Error | Exception hierarchy |
Class<T> | Runtime type information |
ClassLoader | Class loading |
Iterable<T> | The supertype of every collection |
Comparable<T> | The natural-ordering interface |
Process, ProcessBuilder | Process control |
Record | The base of all records |
String s = String.valueOf(42);
int n = Integer.parseInt("42");
double pi = Math.PI;
double sq = Math.sqrt(2);
long now = System.currentTimeMillis();
Class<?> c = Integer.class;
java.util — collections, time, regex, random
The conventional general-utility package:
Collections
Treated in Data structures. The principal types are ArrayList, HashMap, HashSet, Queue, Deque, plus the Collections and Arrays utility classes.
Optional<T>
Optional<User> user = repository.findById(id);
String name = user.map(User::name).orElse("unknown");
Treated in References and primitives and Functional.
Random
The legacy random number generator:
Random r = new Random();
int n = r.nextInt(100); // [0, 100)
double d = r.nextDouble(); // [0.0, 1.0)
Modern code uses java.util.random.RandomGenerator (Java 17+) for a richer interface and pluggable algorithms:
import java.util.random.RandomGenerator;
RandomGenerator rng = RandomGenerator.of("L64X128MixRandom");
int n = rng.nextInt(100);
For cryptographic randomness, java.security.SecureRandom:
SecureRandom sr = new SecureRandom();
byte[] bytes = new byte[16];
sr.nextBytes(bytes);
The conventional discipline: Random for non-security random numbers; SecureRandom for tokens, keys, salts, anything security-sensitive.
Legacy date and time
The legacy types (Date, Calendar, SimpleDateFormat) are largely superseded by java.time (treated below). Most uses of Date and Calendar in modern code should be migrated to Instant, LocalDate, and LocalDateTime.
java.util.regex — regular expressions
Pattern-based matching:
import java.util.regex.*;
Pattern p = Pattern.compile("\\d{4}-\\d{2}-\\d{2}");
Matcher m = p.matcher(input);
if (m.matches()) {
String date = m.group();
}
while (m.find()) {
System.out.println("matched at " + m.start() + ": " + m.group());
}
String redacted = input.replaceAll("\\d{4}-\\d{2}-\\d{2}", "REDACTED");
The principal classes:
Pattern— a compiled regular expression.Matcher— the per-input match state.MatchResult— the read-only view of a match.
Convenience methods on String (String.matches, String.split, String.replaceAll) admit one-shot regex use. For repeated use, compile the Pattern once and reuse:
private static final Pattern DATE = Pattern.compile("\\d{4}-\\d{2}-\\d{2}");
public boolean isDate(String s) {
return DATE.matcher(s).matches();
}
java.util.concurrent — concurrency
Treated in Concurrency. The principal types are executors, futures, locks, atomic variables, and concurrent collections.
java.util.function — functional interfaces
The principal functional interfaces:
| Interface | Signature |
|---|---|
Function<T, R> | R apply(T) |
BiFunction<T, U, R> | R apply(T, U) |
Consumer<T> | void accept(T) |
Supplier<T> | T get() |
Predicate<T> | boolean test(T) |
UnaryOperator<T> | T apply(T) |
BinaryOperator<T> | T apply(T, T) |
Plus primitive specialisations (IntFunction<R>, IntUnaryOperator, etc.).
The full treatment is in Methods and lambdas.
java.util.stream — streams
Treated in Streams.
java.io and java.nio — I/O
Treated in I/O and NIO.
java.net and java.net.http — networking
The original java.net package:
import java.net.*;
URL url = URI.create("https://example.com/api").toURL();
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
try (InputStream in = conn.getInputStream()) {
String body = new String(in.readAllBytes());
}
The legacy interface is rarely used in new code; the modern alternative is java.net.http.HttpClient (since Java 11):
import java.net.http.*;
import java.net.URI;
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://example.com/api"))
.GET()
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
String body = response.body();
// Async:
CompletableFuture<HttpResponse<String>> future = client.sendAsync(request, HttpResponse.BodyHandlers.ofString());
The new client supports HTTP/2, WebSockets, and async operation. For new code, the conventional choice is HttpClient.
For lower-level networking, the Socket and ServerSocket classes:
try (ServerSocket server = new ServerSocket(8080)) {
while (true) {
Socket client = server.accept();
executor.submit(() -> handle(client));
}
}
java.time — modern date and time
The java.time package (introduced in Java 8, replacing the legacy Date/Calendar) provides:
| Class | Purpose |
|---|---|
Instant | An instant in UTC; the conventional timestamp |
LocalDate | A date without time (2024-05-15) |
LocalTime | A time without date (14:30:00) |
LocalDateTime | Date plus time, no zone |
ZonedDateTime | Date plus time, with time zone |
OffsetDateTime | Date plus time, with UTC offset |
Duration | A time-based duration (seconds, nanos) |
Period | A date-based period (years, months, days) |
ZoneId | A time zone |
Clock | A source of current time (admits testing) |
DateTimeFormatter | Parsing and formatting |
import java.time.*;
import java.time.format.DateTimeFormatter;
Instant now = Instant.now();
LocalDate today = LocalDate.now();
LocalDateTime ldt = LocalDateTime.now();
ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("Europe/London"));
LocalDate birthday = LocalDate.of(1985, 5, 15);
Period age = Period.between(birthday, today);
int years = age.getYears();
Duration timeout = Duration.ofSeconds(30);
String formatted = today.format(DateTimeFormatter.ISO_LOCAL_DATE);
LocalDate parsed = LocalDate.parse("2024-05-15", DateTimeFormatter.ISO_LOCAL_DATE);
The classes are immutable and thread-safe — substantial improvements over the legacy types. The conventional contemporary discipline is to use java.time exclusively for new code.
java.text — formatting and parsing
java.text provides locale-aware formatting:
import java.text.NumberFormat;
import java.util.Locale;
NumberFormat fmt = NumberFormat.getCurrencyInstance(Locale.US);
String price = fmt.format(12345.67); // "$12,345.67"
NumberFormat fr = NumberFormat.getCurrencyInstance(Locale.FRANCE);
String price_fr = fr.format(12345.67); // "12 345,67 €"
The conventional choice for currency, percentage, and locale-aware number formatting. For date formatting, use java.time’s DateTimeFormatter instead of the legacy SimpleDateFormat.
java.security — cryptography and security
Hashing, encryption, signing, key generation:
import java.security.MessageDigest;
MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
byte[] hash = sha256.digest("hello".getBytes(StandardCharsets.UTF_8));
String hex = HexFormat.of().formatHex(hash);
import javax.crypto.*;
import javax.crypto.spec.*;
KeyGenerator kg = KeyGenerator.getInstance("AES");
kg.init(256);
SecretKey key = kg.generateKey();
Cipher cipher = Cipher.getInstance("AES/GCM/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] ciphertext = cipher.doFinal(plaintext);
The library covers SHA-1/SHA-256/SHA-512, AES, RSA, ECDSA, key exchange, certificates, and SSL/TLS. The conventional advice: prefer high-level libraries (Bouncy Castle, Tink) for substantial cryptographic code; the standard library covers the basics adequately.
java.lang.reflect — reflection
Runtime type inspection and dynamic invocation:
import java.lang.reflect.*;
Class<?> c = Class.forName("com.example.Widget");
Constructor<?> ctor = c.getDeclaredConstructor(int.class);
Object instance = ctor.newInstance(42);
Method m = c.getMethod("compute");
Object result = m.invoke(instance);
Field f = c.getDeclaredField("count");
f.setAccessible(true);
int count = f.getInt(instance);
Reflection is the principal mechanism for serialisation, dependency injection, ORM mapping, and dynamic dispatch. The standard library uses it heavily; user code uses it occasionally for similar purposes.
The performance cost is non-trivial; for hot paths, method handles (java.lang.invoke.MethodHandle) are faster, and source generators (annotation processors that produce code at compile time) are faster still.
java.sql — JDBC
The traditional database access API:
import java.sql.*;
try (Connection conn = DriverManager.getConnection(url, user, pass);
PreparedStatement stmt = conn.prepareStatement("SELECT name FROM users WHERE id = ?")) {
stmt.setInt(1, userId);
try (ResultSet rs = stmt.executeQuery()) {
if (rs.next()) {
String name = rs.getString("name");
}
}
}
Modern Java applications typically use ORMs (Hibernate/JPA) or higher-level libraries (jOOQ, MyBatis) rather than raw JDBC. The standard library provides the foundation; the rich ecosystem builds on top.
A note on what’s not in the standard library
The standard library is large but not exhaustive. Common needs covered by third-party libraries:
- JSON / XML —
Jackson,Gson(JSON);JAXBlegacy XML;Jackson XMLmodern XML. - HTTP server —
Spring Boot/Micronaut/Quarkus(frameworks);Jetty/Tomcat/Undertow(servers). - Logging —
SLF4J+Logback/Log4j2. - Testing —
JUnit,TestNG,AssertJ,Mockito. - ORM / Database —
Hibernate,JPA,jOOQ,MyBatis. - Reactive programming —
Reactor,RxJava. - Functional —
Vavr,FunctionalJava. - Resilience —
Resilience4j,Hystrix(legacy). - Metrics / Tracing —
Micrometer,OpenTelemetry.
For most application work, the standard library plus a small set of well-known third-party libraries covers the substantial majority of the use cases. The conventional advice: start with the standard library; add libraries as needed.
A note on the size and growth
The Java standard library has grown substantially across revisions: Java 1.0 had ~200 classes; modern Java has thousands. The principal additions:
- Java 5 — generics, autoboxing, enhanced for,
java.util.concurrent. - Java 8 — streams, lambdas,
java.util.function,java.time,Optional. - Java 9 — modules, immutable collection factories, reactive streams.
- Java 11 —
var,HttpClient. - Java 14 — records (preview); pattern matching for
instanceof(preview). - Java 17 — sealed types; pattern matching for
instanceof(final). - Java 21 — virtual threads; pattern matching for
switch(final); record patterns; sequenced collections.
Each subsequent revision adds more. The conventional contemporary approach is to keep the project’s target version reasonably recent (Java 17 or 21 are the current LTS releases) to take advantage of the modern language and library features.