Java Glossary
Canonical terms for this workspace. A term lands here once it can be used correctly, not when it is first mentioned, so this grows as lessons are earned.
Usage in this workspace
Three words are used loosely in ways that would make later lessons ambiguous, and each one hides a mistake that compiles cleanly, so all three are pinned from the start:
Reference:
A value that refers to an object, held in a variable, a field, or an array slot. Everything in Java is passed by value, and for objects the value passed is the reference, which is why a method can mutate what it was given and can never rebind the caller's variable.
Avoid: pointer, handle, alias
Final:
A promise that a variable, field or parameter will not be reassigned. It says nothing about the object on the other end, so a final list can still be cleared.
Avoid: immutable, constant, read-only
Thread-safe:
A property of a class relative to a stated contract: correct behaviour when accessed concurrently, with the contract saying what "correct" means. It is not a synonym for using synchronized, and a class built entirely from thread-safe parts is not automatically one.
Avoid: synchronised, atomic, concurrent
Terms
Aliasing:
The situation where two or more variables hold references to one object, which is what assignment always produces. Mutating through either is observable through both.
Avoid: sharing, pointing, double reference
Autoboxing:
The implicit conversion between a primitive and its wrapper type, performed by calls the source code does not show. Integer.valueOf caches -128 to 127, which is why == on boxed values is correct for small numbers and wrong for large ones.
Avoid: casting, wrapping, promotion
Automatic module:
A plain jar with no module-info.class, which the module system still admits under a name taken from its Automatic-Module-Name manifest attribute or, failing that, derived from its filename. A library that does not set the attribute therefore publishes a name that changes when somebody renames the file.
Avoid: module, unnamed module, modular jar
Behavioural compatibility:
Whether code that still compiles and still links produces the same result as before. It is independent of the other two compatibilities, so the most dangerous release is one that is source-compatible and binary-compatible and quietly answers differently.
Avoid: semantic versioning, bug fix, backwards compatible
Bill of materials:
A pom-packaged artifact that exists only to declare versions, imported into dependencyManagement with import scope. One line then fixes the versions of a whole family of artifacts, which is why a dependency taken from a BOM is declared with no version of its own.
Avoid: parent pom, dependency list, manifest
Binary compatibility:
Whether already-compiled class files still link and run against a new version with no recompilation. Its test is running the old class files, never rebuilding them, because a successful rebuild proves source compatibility and says nothing about this.
Avoid: source compatibility, ABI stability, drop-in replacement
Blackhole:
A sink a benchmark passes a result to so that the value is unambiguously consumed and cannot be treated as unused. JMH can also detect a compiler-supported blackhole mode and use it without any change to the benchmark, and results taken under different modes are not comparable.
Avoid: void return, discarding, no-op
Canonical constructor:
The constructor whose parameters are exactly a record's components, in declaration order. It is generated unless you declare it, and every other constructor on the record has to delegate to it, which is why validation placed there cannot be bypassed.
Avoid: default constructor, primary constructor, main constructor
Carrier thread:
The platform thread a virtual thread is currently mounted on and running against. A virtual thread unmounts from its carrier while it is blocked, which is what makes blocking cheap, and failing to unmount is what pinning means.
Avoid: host thread, worker, OS thread
Checked exception:
A Throwable outside RuntimeException and Error, which the compiler forces every caller to catch or declare. It earns its place only when a reasonable caller can act on the failure, because a caller who can only give up will wrap it or swallow it instead.
Avoid: compile-time exception, declared error, fatal exception
Closeable stream:
A Stream backed by an open operating-system handle, which is what Files.lines, Files.walk and Files.find return. Unlike a stream over a collection it must be closed, and skipping that usually appears to work, because unreachable ones are cleaned up eventually and the descriptors run out only under load.
Avoid: file stream, lazy stream, resource
Committed heap:
The heap the collector currently holds from the operating system, which is what a garbage collection line reports in parentheses. It is neither the occupancy before or after the collection nor the -Xmx ceiling it may still grow towards.
Avoid: max heap, used heap, allocated memory
Compact constructor:
A canonical constructor written with no parameter list, whose body runs before the components are assigned to the fields. Assigning to the parameter is what reaches the field, and assigning to this.field there is a compile error rather than a redundancy.
Avoid: compact form, short constructor, implicit constructor
Compile-time constant:
A static final field of a primitive or String type with a constant initialiser, whose value the compiler folds into every caller's class file. Changing it has no effect on a caller that does not recompile, because no reference to the field survives in the caller at all.
Avoid: final field, immutable value, static field
Compressed ordinary object pointers:
The JVM's default encoding of a reference as a 32-bit heap offset rather than a full-width address, used while the heap is small enough for every object to be reachable that way. It halves the cost of every reference field and every reference-typed array slot, and the JVM decides it ergonomically rather than the programmer choosing it.
Avoid: pointer compression, small heap mode, 32-bit mode
Covariance (of arrays):
The rule that String[] is usable as an Object[], which lets a type error survive compilation and surface as ArrayStoreException. Generics are invariant precisely to close this hole.
Avoid: polymorphism, subtyping, generics compatibility
Critical section:
The region of code that runs while a lock is held. Its extent is a design decision rather than an accident: it should be exactly the span over which the invariant the lock protects is temporarily untrue, which is usually smaller than the method it sits in.
Avoid: locked block, synchronised region, atomic section
Daemon thread:
A thread the JVM does not wait for once the last non-daemon thread finishes, so the process exits with that work unfinished and nothing reported. The status is inherited from the creating thread and can only be set before start.
Avoid: background thread, worker thread, service thread
Data race:
Two accesses to one variable from different threads, at least one of them a write, with no happens-before edge between them. Its presence withdraws the guarantee of sequentially consistent behaviour from the entire execution rather than only from that variable, which is stronger than "sometimes wrong".
Avoid: race condition, concurrency bug, contention
Deadlock:
A cycle of threads each waiting for a lock the next one in the cycle holds, so none proceeds and none of the locks is ever released. One consistent acquisition order across the program prevents it, and the JVM will name the cycle from inside the running process.
Avoid: hang, freeze, lock contention
Decorator (of unified logging):
One of the context fields -Xlog prepends to each line, such as the wall-clock time, the uptime, the level or the tags. Choosing them is what makes a log analysable later, because the fields absent from a line cannot be recovered from it.
Avoid: decorator pattern, prefix, formatter
Defensive copy:
A copy taken so that a reference cannot be used to change an object from outside it: on the way in so a caller's later mutation cannot reach a field, and on the way out so a returned reference cannot either. The second half is the half that gets forgotten.
Avoid: deep copy, clone, snapshot
Dependency mediation:
The rule by which a build picks one version when the graph asks for several: the declaration nearest the project wins, and a tie at equal depth is broken by whichever was declared first. It is not "newest wins", which is the common assumption and the reason adding one dependency can silently downgrade another.
Avoid: version resolution, conflict resolution, upgrade
Dependency scope:
A declaration of which classpaths a dependency belongs on and whether it reaches a consumer. test and provided do not propagate at all, which is the mechanism behind most failures that appear only once something is packaged or reused.
Avoid: visibility, dependency type, phase
Downstream collector:
A collector handed to another one, such as groupingBy, partitioningBy or teeing, which runs against each group or branch rather than against the whole stream. It is what turns a grouping into counts, sums or a nested map without a second pass.
Avoid: nested collector, sub-collector, inner reduction
Dummy:
A test double passed only to satisfy a signature and never actually called. If it is called the test should fail, which is why throwing from every method is a sound implementation of one.
Avoid: stub, mock, null object
Encounter order:
The order in which a stream's elements arrive, where the source has one. findFirst, sort stability and the order of a collected List are all defined against it, and a source such as a HashSet gives them nothing to be defined against.
Avoid: sort order, iteration order, sequence
Erasure:
The compiler's discarding of type arguments, which leaves List<String> and List<Integer> as one class at run time. Every restriction on generics follows from it, and so does a ClassCastException on a line that contains no cast.
Avoid: type deletion, unboxing, runtime generics
Ergonomics:
The JVM's practice of computing a flag's value at startup from the machine it finds, reported as {ergonomic} rather than {default}. An ergonomic value is not a constant and changes with the machine or the container limit, silently and with no flag touched.
Avoid: default, tuning, autoconfiguration
Escape analysis:
The compiler's proof that an object cannot be observed outside the method that created it, which permits it not to be created at all. It is an optimisation with nothing in the specification promising it, so it can stop applying when unrelated code changes what gets inlined.
Avoid: garbage collection, stack allocation, optimisation pass
Exhaustive switch:
A switch whose labels the compiler can prove cover every possible value, which is what permits omitting default. Omitting it is the point rather than an oversight, because adding an alternative then fails compilation at every place that has to decide again.
Avoid: complete switch, total switch, default-free switch
Fake:
A working implementation of an interface, simplified enough to use in a test, such as a map standing in for a repository. It encodes behaviour rather than an expected sequence of calls, so it survives a refactor that would break a mock with ordered expectations.
Avoid: mock, stub, in-memory copy
Final field freeze:
The guarantee that a thread obtaining a reference only after construction has finished sees that object's final fields correctly initialised. It holds even when the reference itself was published through a data race, which is why a properly built immutable object can be shared with no synchronisation at all.
Avoid: immutability guarantee, constructor barrier, safe init
Fork (of a benchmark):
A separate JVM process a harness starts so that one benchmark's compilation and profiling history cannot influence another's measurement. Running a single fork is the commonest reason two benchmarks appear to differ when they do not, or appear identical when they differ.
Avoid: thread, iteration, process fork
Fragile base class problem:
The coupling inheritance creates in both directions: a superclass author breaks subclasses by changing behaviour that looked internal, and a subclass author breaks by depending on more than the superclass promised. It is why every protected member is published API.
Avoid: tight coupling, bad inheritance, base class rot
Functional interface:
An interface with exactly one abstract method, which is what lets a lambda or a method reference stand in for an instance of it. The @FunctionalInterface annotation states and enforces the intent, and is never required for the lambda to work.
Avoid: lambda interface, callback, SAM type
Goal:
A single unit of work a build plugin can perform, named as plugin:goal. Goals are what actually run, and a phase only names the point at which one has been bound to run, so "what does this command do" is always answered by listing goals.
Avoid: task, phase, command
Happens-before:
The ordering relation that makes one action's effects visible to, and ordered before, another's. It is the only thing that makes a concurrent read and write pair safe, so every synchronisation construct is worth precisely the edges it creates and nothing more.
Avoid: before, ordering, synchronisation
Hiding:
A subclass declaring a static method or a field with the same name as one in the superclass. It resolves on the declared type of the reference rather than the runtime type of the object, which is the opposite of overriding and looks identical in the source.
Avoid: overriding, shadowing, masking
Humongous allocation:
In G1, an object at least half a region in size, which is allocated directly into contiguous regions rather than through the ordinary young path. It appears in a garbage collection log by name, and a stream of them is a sizing problem rather than a collector problem.
Avoid: large object, big allocation, old generation allocation
Interning:
Placing a value in a shared pool so that identical values are one object. String literals and compile-time constants are interned, which makes == on strings appear to work until a value is built at run time.
Avoid: caching, deduplication, pooling
Invariance (of generics):
The rule that List<String> is not a List<Object>, whatever the relationship between the type arguments. It is the deliberate opposite of array covariance, and it is what moves the error from run time to compile time.
Avoid: strictness, missing polymorphism, type mismatch
Lifecycle phase:
A named point in a build's ordered sequence, such as compile, test or package. Naming one runs every phase before it as well, which is the single rule that predicts what any build command will do.
Avoid: goal, step, target
Local (of a date or time):
A value naming a reading on a calendar or a wall clock with no zone attached, which is what LocalDate, LocalTime and LocalDateTime are. None of them is a point on the universal timeline, so none converts to an Instant without being told a zone, and using one as a timestamp is the most common mistake in the time API.
Avoid: naive time, zoneless, floating time
Metaspace:
The off-heap area holding the metadata of loaded classes, meaning their bytecode, constant pools and field layouts. It is bounded separately from the heap and is unbounded by default, so a classloader leak exhausts native memory rather than heap.
Avoid: permgen, heap, class cache
Method descriptor:
The encoding of a method's parameter and return types which, with its name, is the method's identity inside a class file. Two methods differing only in return type are one method in the source language and two unrelated methods here, which is why narrowing a return type breaks callers that do not recompile.
Avoid: signature, prototype, type erasure
Mock:
A test double carrying expectations about how it is called, which are checked and can fail the test on their own. It tests the implementation's choice of interactions rather than its promise, which is why it is the double most likely to fail on a change that broke no behaviour.
Avoid: stub, fake, double
Module:
A named, compiler- and runtime-recognised unit declared by a module-info.java, stating what it requires and which of its packages it exports. A type is usable outside its module only if it is public, its package is exported, and the using module reads this one; a public class in an unexported package is invisible past the module boundary.
Avoid: JAR, package, library (a JAR is a packaging format; a module is a declared boundary the compiler and runtime both enforce, and a JAR with no module-info.class is not one)
Module path:
The list of JARs and directories the module system searches to resolve requires directives, parallel to the class path but a genuinely different list. A plain JAR placed here becomes an automatic module; the identical JAR placed on the class path instead becomes part of the unnamed module, with no encapsulation at all.
Avoid: class path as a synonym, a build-tool concept, a classpath entry
Monitor:
The intrinsic lock and wait set that every object carries, entered by a synchronized method or block and released on exit or on a call to wait. Locking on an object anyone else can reach publishes its monitor, and then anyone else can hold it.
Avoid: lock object, mutex, semaphore
Natural ordering:
The ordering a type defines for itself by implementing Comparable. A sorted collection uses it instead of equals, so two elements that compare as zero are one element as far as a TreeSet is concerned.
Avoid: default sort, comparison, ranking
Object header:
The fixed block of JVM bookkeeping in front of every instance's fields, invisible from the source and counted in every allocation. On a small object it is most of the object, which is why a record of two int fields costs three times what its fields do.
Avoid: record header, metadata, object overhead
Overload resolution:
The compiler's choice, made from the static types of the arguments, of which same-named method a call binds to. It happens once at compile time and never again, so a caller holding a value under a more general type gets a different overload than its runtime class would suggest.
Avoid: dynamic dispatch, overriding, polymorphism
PECS:
Producer extends, consumer super: ? extends T for a structure you only read from, ? super T for one you only write to. A parameter that must do both takes a plain T and gives up the flexibility, which is the trade rather than a defect.
Avoid: wildcards, variance, bounded generics
Pinning:
A virtual thread blocking without being able to unmount, so it keeps its carrier thread occupied and removes it from service for the duration. What causes pinning has changed across releases, so it is established by measuring on the release being deployed rather than from anything written about an earlier one.
Avoid: blocking, sticking, thread affinity
Platform thread:
A thread backed one to one by an operating-system thread and its stack, which is what new Thread has always produced. The stack is why they are counted in thousands rather than millions, and why pools exist at all.
Avoid: real thread, native thread, kernel thread
Probe effect:
The change in a concurrent program's behaviour caused by observing it, such as a log line shifting the scheduling enough to hide the very race it was added to catch. It is the reason a concurrency bug is made to reproduce reliably before anything is changed.
Avoid: heisenbug, observer effect, timing issue
Raw type:
A generic type used with no type argument, such as List in place of List<String>. It switches off checking for every member whose signature mentions the parameter, which is how a wrong element gets in silently and surfaces as a cast failure somewhere else entirely.
Avoid: untyped collection, legacy generic, unparameterised type
Reflection:
Reading a class's own shape, and calling its members, at run time rather than compiling against them directly: Class, getDeclaredFields/getDeclaredMethods, Field.get/set, Method.invoke. It operates within the same encapsulation the module system enforces everywhere else, so a private field in a package neither exported nor opened refuses setAccessible exactly as it refuses a direct reference.
Avoid: introspection as a vague synonym, a library (it is a JVM capability every framework here reuses), something that bypasses encapsulation rather than being subject to it
Reproducible build:
A build that turns the same source into byte-identical output. Archive entry timestamps defeat it by default, so it has to be asked for explicitly, and until it is, two builds of one commit cannot be shown to have produced the same artifact.
Avoid: deterministic build, repeatable build, clean build
Resident memory:
The total memory the operating system charges to the JVM process, which is the heap plus metaspace plus thread stacks plus the code cache plus native and direct buffers. It is what a container limit is enforced against, and -Xmx bounds only the first term of it.
Avoid: heap usage, virtual memory, max heap
Retention policy:
Whether an annotation survives past source (SOURCE, discarded by the compiler), into the class file only (CLASS, the default when @Retention is left off entirely), or into the running VM (RUNTIME, the only one reflection can actually see). A framework annotation with no stated retention compiles, attaches, and is invisible to every reflective check, with no error anywhere.
Avoid: assuming an annotation is reflectively visible by default (the default is CLASS, not RUNTIME), a compiler-only concept, an access modifier
Runtime image:
The directory jlink produces, containing a working java launcher plus only the modules actually reached from the ones named on its command line. It links explicit modules only; an application depending on even one automatic module cannot be linked into one at all.
Avoid: JRE, JDK, a smaller JDK (it is not a general-purpose installation, only the modules it was built to include)
Scalar replacement:
The optimisation that follows escape analysis, holding a non-escaping object's fields in registers or on the stack instead of allocating the object. The allocation then does not appear in a measurement of bytes per operation at all, because it never happened.
Avoid: inlining, stack allocation, elision
Sealed hierarchy:
A supertype whose permitted direct subtypes are fixed at compile time, so the set of alternatives is closed and the compiler can enumerate it. That is what makes a switch over it exhaustive with no default.
Avoid: closed class, final hierarchy, restricted inheritance
Short-circuiting operation:
A stream operation that can finish without pulling every element through the pipeline, such as findFirst, anyMatch or limit. It is what makes an infinite source usable, and it is what an operation such as sorted takes away, since sorting has to see everything first.
Avoid: early exit, lazy operation, break
Source compatibility:
Whether code that compiled against the old version still compiles against the new one, unchanged. Its test is a recompile, and passing it says nothing about whether already-compiled callers will still run.
Avoid: binary compatibility, API stability, non-breaking change
Spy:
A test double that records how it was called so the test can inspect it afterwards, or a wrapper that delegates to a real object while recording. It moves the check to after the call instead of declaring it in advance, which is what separates it from a mock.
Avoid: mock, stub, listener
Strong encapsulation:
The module system's rule that a public type is reachable from outside its module only if its package is also exported and the calling module reads this one, closing the class-path-era hole where reflection could reach any private member of any JAR. opens reopens a package for reflection at run time only, without restoring compile-time access to it.
Avoid: access modifiers alone, information hiding as a synonym (this is enforced by the runtime, not only a compiler convention), sealing (a different mechanism, for a type hierarchy)
Stub:
A test double that returns canned answers and checks nothing about how it was used. It supplies input rather than expectations, so a test built only on stubs is asserting on results.
Avoid: mock, fake, dummy
Suppressed exception:
An exception attached to another rather than replacing it, which is what try-with-resources does when a resource fails to close while an exception from the body is already propagating. A hand-written finally loses the original instead, with no trace that it happened.
Avoid: secondary exception, ignored exception, nested exception
Terminal deprecation:
Deprecation with forRemoval = true, which the platform treats as a different signal rather than a stronger adjective: the compiler warns about it by default, in its own removal category, where ordinary deprecation is silent without -Xlint:deprecation. It is a stated intention and not a guarantee, since the platform has withdrawn one.
Avoid: deprecated, obsolete, scheduled for deletion
Terminal operation:
The stream operation that makes the pipeline run and consumes it, such as forEach, collect or count. Nothing before it executes, and nothing after it is possible on that stream, because a second terminal call throws.
Avoid: final operation, sink, evaluation
Test double:
Any stand-in for a real collaborator in a test: a dummy, a stub, a spy, a mock or a fake. The general word is worth keeping because those five differ in what they let a test conclude, and treating them as synonyms is what produces a suite that passes while proving nothing.
Avoid: mock, fake, stub
Test engine:
A plug-in that teaches the test platform one way of writing tests, such as Jupiter for current tests or Vintage for JUnit 4 ones. Nothing runs without one present, and a build tool that supplies one automatically will hide its absence from the project's own declarations.
Avoid: runner, framework, platform
Test instance lifecycle:
The rule deciding how many instances of a test class get created: one per test method by default, or one for the whole class. The default is what makes a field written by one test invisible to the next, so changing it trades isolation for shared setup.
Avoid: scope, fixture, lifecycle
Thread stack:
The per-thread reservation holding that thread's call frames, sized by -Xss and unaffected by -Xmx. Exhausting one raises StackOverflowError in that thread alone, which is a different kind of failure from a shared pool running out.
Avoid: heap, call stack trace, stack trace
Thread-local allocation buffer:
The slice of the heap handed to one thread so that its ordinary allocations are a pointer bump needing no coordination with other threads. It is why allocation itself is cheap, and it says nothing about the later cost of tracing or copying what was allocated.
Avoid: free allocation, thread-local variable, buffer pool
Total order:
A comparator or natural ordering under which no two distinct elements compare as zero. Sorted collections need one, and a chain of keys provides it only if the last key is unique per element.
Avoid: full sort, strict ordering, complete comparator
Transitive dependency:
A dependency you never declared, present because something you did declare needs it. Most of a project's classpath arrives this way, at versions chosen by mediation rather than by anyone, which is why relying on one you did not ask for breaks on somebody else's upgrade.
Avoid: indirect import, sub-dependency, nested library
Uber jar:
A single jar holding the project's own classes together with the unpacked contents of all its dependencies, so it runs with nothing else on the classpath. The convenience costs a far larger artifact and flattens every dependency's identity, including its licence information, into one file.
Avoid: fat jar, shaded jar, bundle
Unnamed module:
Where every class loaded from the class path lives: it has no name, so nothing can require it, and it reads every other module while exporting and opening all of its own packages. Whether a JAR's code ends up here or in a real module is decided by which path it is launched on, not by anything in the JAR itself.
Avoid: automatic module (that's a module-path JAR with no descriptor; this is class-path code specifically), default module, anonymous module
View:
A collection that reads through to another one rather than holding its own contents, which is what Collections.unmodifiableList and Map.values return. It refuses writes through itself and still shows every change made to the collection behind it.
Avoid: copy, snapshot, wrapper
Wither method:
A method returning a new instance that differs in one component, conventionally named withX. It is the immutable replacement for a setter, and it makes the cost visible, since every call allocates.
Avoid: setter, mutator, copy method