Java autoboxing/unboxing madness (2007)
arstechnica.com
arstechnica.com
Otherwise, if the second and third operands have types that are convertible (§5.1.8) to numeric types, then there are several cases:
... binary numeric promotion (§5.6.2) is applied to the operand types, and the type of the conditional expression is the promoted type of the second and third operands.
... If either operand is of type double, the other is converted to double.
To some extent both languages were trying to deal with C++'s having three different kinds of types: Atomics, objects and structs. If I had to tell a made-up story, I'd guess that Java's designers looked at that and decided structs were in many ways just a more limited version of classes with some confusing semantic quirks, and therefore decided to nix them. That left atomics and objects, and the rest is history.
C#'s folks then reconsidered it and realized that, from a high level perspective, atomics are really just a special case of structs. (Side note: still telling that made-up story.) So they kept structs, unified them with atomics in the language,* and let the compiler deal with the rest. It works well and seems like an obviously better way to do it, but I'm not sure that insight would have been so obvious in the moment.
* Edit: Oh, and made structs a subtype of System.Object. Unlike Java, .NET's more-or-less fully object-oriented.
Java wanted to enforce reference semantics (and heap storage) for classes, but still wanted to retain value semantics (and stack storage) with fundamental types for performance reasons. The result is the mess we have now.
They just wanted to simplify the compiler.
Here's an article that goes into it in more detail: http://www.javaworld.com/article/2150208/java-language/a-cas...
Why should I care
Let's say you were processing map data for OpenStreetMap, which has about 3,720,000,000 nodes [1], and for each node you want to store a latitude and a longitude.If you use a pair of primitive ints for the latitude and longitude you'll need 8 bytes of memory per node, or 30 gigabytes total.
(Ignoring caching and assuming UseCompressedOops is enabled) Each boxed int will take 4 bytes for the primitive and 8 bytes of housekeeping overhead and class reference, rounded up to 16 bytes because memory boundaries must be divisible by 8, plus you'll need a reference to that object which is another 4 bytes.
So replacing those two primitive ints with boxed ints will take 40 bytes of memory per node, or 150 gigabytes total. And now you've got a 150 gigabyte heap to garbage collect :)
That memory increase is the difference between an EC2 instance that costs $1600/year and one that costs $13000 - and primitives will probably perform better as well.
And if you want to store more than two ints for each node, it could be the difference between an off-the-shelf EC2 server and needing to get hold of special high memory servers.
In that backdrop, seemingly bad trade off get made for execution performance and to compile the code in a reasonable amount of time. More accurate would've been that the decision has not aged very well.
So. Much. Typing. I'll take the occasional "gotcha" that's not terribly difficult to diagnose or fix over the world we had before.
Autoboxing and generics are clearly bolted onto Java and it would be designed differently if they were there in the beginning. This makes me doubtful when Go adherents say that they can just add generics later.
They should have killed the primitive/object distinction, turning the primitives into stack-allocated objects and rewritten the collections libraries. But no, syntactic sugar is better than actually fixing the problem for those that want a fix.
That would have been a mistake, because it would have made Java unreasonably inefficient for manipulating large data sets. You really need both, which is why they included both originally.
Autoboxing is a problem in that it allows you to pretend you don't have to check for nulls when you really should be checking for nulls. If I had my druthers I'd forbid autoboxing on my projects.