Tutto viene dall'hardware.
Un byte è la più piccola unità di memoria indirizzabile sulla maggior parte dell'hardware.
Ogni tipo che hai appena citato è costruito da alcuni multipli di byte.
Un byte è 8 bit. Con ciò potresti esprimere 8 booleani ma non puoi cercare solo uno alla volta. Indirizzo 1, indirizzo a tutti 8.
Ed era così semplice, ma poi siamo passati da un bus a 8 bit a un bus a 16, 32 e ora a 64 bit.
Ciò significa che mentre possiamo ancora indirizzarci a livello di byte, non possiamo più recuperare un singolo byte dalla memoria senza ottenere i byte vicini.
Di fronte a questo hardware, i progettisti del linguaggio hanno scelto di permetterci di scegliere i tipi che ci hanno permesso di scegliere i tipi che si adattano all'hardware.
Puoi affermare che un tale dettaglio può e deve essere sottratto soprattutto in un linguaggio che mira a funzionare su qualsiasi hardware. Ciò avrebbe problemi di prestazioni nascosti ma potresti avere ragione. Non è successo in quel modo.
Java in realtà cerca di farlo. I byte vengono automaticamente promossi in Ints. Un fatto che ti farà impazzire la prima volta che provi a fare qualche serio lavoro di spostamento.
Quindi perché non ha funzionato bene?
Il grande punto di forza di Java nel passato era che si poteva sedere con un noto algoritmo C, digitarlo in Java e con lievi modifiche avrebbe funzionato. E C è molto vicino all'hardware.
Mantenere quella dimensione e sottrarre dimensioni ai tipi integrali non ha funzionato insieme.
Quindi avrebbero potuto. Semplicemente no.
Forse il programmatore non vorrebbe che qualcuno fosse in grado di usare un numero maggiore di una certa dimensione e questo gli consente di limitarlo.
Questo è un pensiero valido. Ci sono metodi per farlo. La funzione di bloccaggio per uno. Una lingua potrebbe arrivare al punto di creare limiti arbitrari nei loro tipi. E quando quei limiti sono noti al momento della compilazione, ciò consentirebbe l'ottimizzazione del modo in cui quei numeri sono memorizzati.
Java non è proprio quella lingua.