Escape analysis doing the heavy lifting here. Until it's fully reliable you're still guessing at allocation.
Since being created, the Java pitch was "don't worry about low-level stuff like value/reference classes, a Sufficiently Smart Compiler will automatically pick the best option given your code and runtime profiling".
What changed, why suddenly they adopt C++ features they explicitly excluded?
Good technical overview, and I fully agree with the conclusion's sentiment at the end:
``` Declaring a value class is first and foremost a semantic decision. It tells our fellow programmers that its instances are defined entirely by their state and do not need identity. That clearer model is valuable in itself! The JVM’s additional freedom to optimize how those values are represented is a welcome bonus. ```
Many developers seem to think that "go value go broom", but the truth is much more nuanced and the idea should not be to think about "but performance" but to think about the nature of your underlying data. At the very least this integrates some core DDD lessons directly into language. I'm glad tearing isn't turned on by default exactly for this reason.
Java was always a language that geared itself towards making libraries easy to use, putting much faith in the library author and strong encapsulation. Now, experts can gain significantly more performance from the JVM, while more humble programmers are avoided from creating bugs they will not expect.