Это было дизайнерское решение Java, которое некоторые считают ошибкой. Контейнеры хотят, чтобы объекты и примитивы не были производными от Object.
Это то место, которое разработчики .NET извлекли из JVM и реализовали типы значений и обобщения, так что во многих случаях упаковка исключена. В среде CLR универсальные контейнеры могут хранить типы значений как часть базовой структуры контейнера.
Java решила добавить 100% универсальную поддержку в компилятор без поддержки JVM. JVM, какова она есть, не поддерживает «не объектный» объект. Дженерики Java позволяют вам притвориться, что оболочки нет, но вы все равно платите цену производительности бокса. Это ВАЖНО для определенных классов программ.
Бокс - это технический компромисс, и я чувствую, что детали реализации просачиваются в язык. Автобоксинг - хороший синтаксический сахар, но все же снижает производительность. Во всяком случае, я бы хотел, чтобы компилятор предупреждал меня, когда он автоматически упаковывается. (Насколько я знаю, возможно, сейчас я написал этот ответ в 2010 году).
Хорошее объяснение SO о боксе: зачем некоторым языкам нужны бокс и распаковка?
И критика дженериков Java: почему некоторые утверждают, что реализация дженериков в Java плохая?
В защиту Java легко оглянуться назад и критиковать. JVM выдержала испытание временем и во многих отношениях является хорошей разработкой.