|
Ever since the JDK 1.0 days, I didn’t get why there was this C/C++ carry-over inconsistency of manually-boxed types and non-Objects primitive types separated from Objects. A type hierarchy, patterned similar to Ruby’s as an example, makes the most sense: - Object contains a Class that it derrives from (no BaseObject or Modules) - Class is an Object - String is an Object - Boolean is a two-value singleton of true and false - Number is an abstract subclass of Object - Decimal and Integer are abstract subclasses of Number - Float, Double,
LongDouble, BigDecimal are concrete subclasses of Decimal - SignedByte, Byte, Short, UnsignedShort, Int, Unsigned, Long, UnsignedLong, Char, BigInt are concrete subclasses of Integer (or U/I/F## types reminiscent of Rust instead of C type names) and so on. Then there is no boxing/unboxing of simple types or literals because they are one-and-the-same, and no there’s no confusion about how to interact with any truly generic type of value. |
The reason Java isn't a 'pure' object-oriented language is simply performance.
Suppose everything - even every int - is heap-allocated. You now need a very sophisticated JIT compiler (as in, better than any we have today), or it's going to run dog slow. Having a huge number of needless allocations happening at every step is going to:
1. Slow things down by doing vastly more heap allocations that you otherwise would (even with Java's ultra-fast allocations)
2. Slow things down by doing violence to your code's locality and cache behaviour, because your ints no longer live in the stack
3. Slow things down by doing violence to your code's locality and cache behaviour, because Java objects are bloated compare to raw ints
4. Slow things down by hugely increasing garbage-collection pressure
If Gosling had taken that route, we wouldn't be talking about Java today.