C++ doesn't need this kind of restriction because it makes the difference between references and values explicit, so it's actually possible to explicitly ask for a vector of values, rather than only being able to ask for a vector of references and artificially restricting the language so that it can be optimised to a vector of values.
(Yeah I know you can't derive from int in C++ but that's for other reasons.)
I agree C++ makes it too easy to accidentally copy data, but at least you can copy data!
struct MyStruct
a::Int64
b::Float64
end
Since the size of each field is known (8 bytes), the size of the whole struct, and thus the size of each instance of that struct, is known - 16 bytes. This is crucial information for inlining, loop unrolling, copy elision, deciding which register(s) to place the object in, getting rid of indirections through pointers.. If you'd allow to subtype MyStruct, the compiler wouldn't be able to know ahead of time what the size of a MyStruct object is and would either have to box every access (introducing pointers which have to be chased on access) or defer A LOT of work to runtime. With boxing, you almost immediately lose lots of opportunities to SIMD or otherwise optimize your code, because you have to keep a whole lot of extra type information around at runtime that's just not necessary when all your objects in a e.g. Vector{MyStruct} have the same size anyway.1. the JVM does not support generics as a language construct, and are simply a compiler feature of Java
2. the JVM and Java differentiates primitive and reference types, Integer being a reference (boxing) type of the primitive type int. And, generics do not support primitive types anyway.
The JVM implementations are incredible pieces of machinery, and even if they did not pack or stride their primitive arrays -- which they absolutely do -- the JVM & compilers will handle an incredible amount of runtime memory layout and packaging.