Clojure does hot code reloading as a built in. You essentially send code to a running system and you change it. It’s enabled by a dynamic class loader. I wouldn’t say it’s common outside of Clojure though, the whole language and ecosystem is built around this concept.
To be clear: JVM enables the feature, so “technically” JVM allows hot code reload. Not sure how useful this is in practice for non-Clojure JVM users.
Runtime code generation is a common optimization in java frameworks. End-users may never see it but the majority of popular frameworks use it under the covers.
Debuggers also use the functionality to allow live code editing and expression evaluation when paused on a breakpoint
generating code during runtime is rather common in Java frameworks.
Most really popular frameworks use it. Spring for AOP and Hibernate for "bytecode enhancement".
There's a number of libraries, like CGLIB and ByteBuddy designed explicitly to make this easy.
There are limits to how much you can change in existing loaded class code, but if you are just loading up new dynamically generated code you can do pretty much anything.
Its a big reason why some of these Java frameworks are so fast. They can generate highly optimized code on the fly, load it, and have it running alongside the existing app code within a few hundred milliseconds. And the Java JIT will optimize it as if the code was there the whole time.
This makes performance optimizations easy that would be impossible in AOT languages like Go, C, C++, Rust, etc
java.lang.invoke.MutableCallSite supports linking one particular MethodHandle at a time which the VM will optimize for. Then you can use MutableCallSite::setTarget with another MethodHandle which will cause recompilation of affected paths.
I want to make sure you're talking about the same thing.