I know its a faux pas in the Java world to acknowledge the existence of .NET, but how does this differ from .NET structs? Value types, generic specialization, boxing - a quick skim makes it looks like they picked the same choices.
The article has a section about that. For me, a struct in C/C# can be modified and is passed by copy while a value class can not be modified and is passed by value. I do not think you can do stack allocation in Java.
The mutability difference is that part of a struct can be modified in place, which value classes can’t: the value of a complete value-class variable (or array slot) can only be modified (reassigned) as a whole. This is presumably because object references to value-class objects can be created, and those objects should be immutable so their identity doesn’t matter.