Java changes & JVM limits
Understand method bodies, structural reload, field initialization, enum edits and reflective visibility.
Method bodies: the everyday loop
Compile a supported change to a watched class and the agent replaces its implementation in the running JVM. Existing object fields remain on a method-body-only path. Core fixtures observe repeated parent/child virtual dispatch and super calls without a new process.
Use this as your first verification case before trying structural or framework changes. A bytecode change can succeed while a later framework refresh fails; check the full outcome.
Add and remove members on a stock JDK
Reclazz’s companion engine supports added/removed methods and fields without requiring a patched JVM. Hot-compiled calls to new methods and supported direct field accesses are routed through the companion. Compile affected watched callers too.
The original Class does not gain those members on a stock JVM. Arbitrary Class.getMethod / getDeclaredField consumers cannot discover them. Supported framework adapters, such as the documented Jackson path, are explicit exceptions.
When a member is removed, scans stop seeing it, while code already holding it can retain the last implementation. Removal is not a revocation of every old reference.
New instance fields on existing objects
On the stock companion path, an isolated initializer can run for each existing object on that field’s first read. It may use that object’s existing state. A later save preserves a value already initialized or written, including null.
private final List<String> cache = new ArrayList<>();
private int retries = 3;Conditional initializers have a bounded single-constructor path. Constructor-argument dependencies, entangled writes and unsupported instruction shapes cannot be inferred safely: the field retains its type default and the diagnostic names why.
Separately reloaded watched callers can share the owner’s added-field store in the recorded SapMachine 17/21 lanes. This does not certify field-type changes or every inherited-field/classloader shape. Enhanced JVMs have real fields; objects created before that reload retain native type defaults.
New static fields and constants
A compile-time constant or an isolated static initializer can initialize an added static field. Supported forward conditional/switch expressions execute only the selected arm. Existing static blocks and values are not reset, and changing an initializer later does not reinitialize a field already populated.
Loops, inseparable side effects and unsupported control flow leave the added field at its type default and produce a reason. A compile-time constant already inlined into callers needs those callers rebuilt; AutoCompile can rebuild detected watched sources. Unwatched consumers are outside that repair.
Enums: preserve ordinals
Appending a constant and removing the final constant have documented support on JDK 17–25, including values(), valueOf, switches and existing EnumMap/EnumSet instances. Arrays your application sized from the old enum length remain the old size.
Insertion, reordering and non-tail removal renumber ordinals and are refused. Restart for the change and account separately for persisted ordinal data. Do not infer coverage of a newer JDK from the target Java version.
Interfaces and superclass edits
Adding or removing implemented interfaces requires a compatible enhanced-redefinition JVM. On a stock JVM, the interface change is refused.
Reclazz does not apply a new superclass. Eligible method bodies may reload while retaining the old hierarchy; methods dependent on the changed parent remain pinned. Unsafe signatures or constructors can refuse the whole save. Restart to complete the hierarchy change and inspect partial/refused reporting.
Sources & version scope
Documentation source 1.4.0 · evidence baseline 75535bd · reviewed 19 October 2026. Check your installed artifact; source features may postdate a release.