The reason is very simple: **efficiency**.  In multiple ways.

1. The closer the data types of a language match the underlying data types of the hardware, the more efficient the language is considered to be. (Not in the sense that your programs will necessarily be efficient, but in the sense that you may, if you really know what you are doing, write code that will run about as efficient as the hardware can run it.) The data types offered by Java correspond to bytes, words, doublewords and quadwords of the most popular hardware out there.  That's the most efficient way to go.

1. If the decision had been made to map everything to a fixed-size 64-bit long, this would have imposed a huge penalty on 32-bit architectures that need considerably more clock cycles to perform a 64-bit operation than a 32-bit operation.  Also, on hardware that is not too picky about memory alignment, an array of 100 bytes can occupy only 100 bytes of memory, but if bytes are mapped to longs, the same array will occupy an order of magnitude more memory.

1. Your notion of determining the size of an integer dynamically depending on how big the number passed in was is too simplistic; there is no single point of "passing in" a number; the calculation of how large a number needs to be has to be performed at runtime, on every single operation that may require a result of a larger size: every time you increment a number, every time you add two numbers, every time you multiply two numbers, etc.  That would have been very inefficient.

1. Subsequently, having numbers of potentially different sizes floating around in memory would complicate ***all*** operations:  Even in order to compare two numbers, the runtime would first have to make sure that both numbers to be compared are of the same size.

1. Certain bitwise operations rely on the integer having a specific size. Having no pre-determined specific size, these operations would have to be emulated. That represents a lot of overhead.

1. Changing the size of a number at runtime essentially means that it has to be polymorphic.  This in turn means that it cannot be a fixed-size primitive allocated on the stack, it has to be an object, allocated on the heap.  That is terribly inefficient.  (Re-read #1 above.)