When did agreeing with me become inherently tabu?
In Java, ints do not behave both ways. Ints are base types, and are passed, as all base types are, by value. Integers are Objects, and are passed, as all Objects are, by pointer-value. There are no Java Objects that revert to being passed as the sum of their fields (with the exception of uboxed numbers, which doesn't count).
Autoboxing is the silent up-conversion of a base type to an Object. Ex:
Integer i = (int)2;
Java also has automatic unboxing:
int i = new Integer(2);
If you switch down to a Java 1.4 compiler, and try to compile the following:
Integer x = new Integer(1);
Integer y = new Integer(2);
Integer z = x + y;
You will get an error indicating that two Objects can not be added together. In Java 5, this was solved by adding autoboxing/unboxing; the third line will unbox the Integers to ints, add them, and autobox them back in to an Integer.
It isn't hacky because it's intuitive, and it isn't in the runtime for two reasons: one, for backwards compatibility. Two, you can't overload operators in Java. As we've already discussed, Java doesn't believe in operator overloading, with the exception of number objects (because they're being used to do math on numbers which is intuitive) and java.lang.Strings (because typing out .concat is tedious and is less intuitive than using +). There simply aren't any other conditions where the + operator, or any operator for that matter, can be used intuitively.
C# structs are hacky because they aren't intuitive, and because they don't inherit behavior from their parent class, System.Object.
If you really are going to insist that autoboxing is hacky, you should also complain about the automatic import of java.lang.*, because it's equally as hacky, and less intuitive.