This is because BigInteger is not really close to being primitive. It is implemented using an array and some additional fields, and various operations include complex operations. For example, here is the add implementation:
public BigInteger add(BigInteger val) { if (val.signum == 0) return this; if (signum == 0) return val; if (val.signum == signum) return new BigInteger(add(mag, val.mag), signum); int cmp = compareMagnitude(val); if (cmp == 0) return ZERO; int[] resultMag = (cmp > 0 ? subtract(mag, val.mag) : subtract(val.mag, mag)); resultMag = trustedStripLeadingZeroInts(resultMag); return new BigInteger(resultMag, cmp == signum ? 1 : -1); }
Primitives in Java are types that are usually implemented directly by the processor of the host machine. For example, every modern computer has a machine language instruction for integer additions. Therefore, it can also have very simple byte code in the JVM.
A complex type such as BigInteger cannot usually be processed this way and cannot be translated into simple byte code. This cannot be primitive.
So your question might be "Why is there no operator overloading in Java". Well, that part of the philosophy of language.
And why not make an exception, for example, for String ? Because this is an exception not only from one operator. You must make an exception for the operators * , / , + , - , << , ^ and so on. And you still have some operations in the object itself (for example, pow , which is not represented by an operator in Java), which for primitives is handled by special classes (for example, Math ).
Realskeptic
source share