В ответ на риторический вопрос @Jon Skeet:
Затем другой класс ссылается на Bar, поэтому JVM нужен код для него ... как бы вы предположили, что он находит файл?
Предположим (гипотетически), что формат файла классов Java представляет вложенные / внутренние классы, встраивая их в файл классов для самого внешнего класса. Двоичное имя для бара: "Lsome/pkg/Foo$Bar;
". Загрузчик классов может разделить имя на символ "$
", использовать первую часть, чтобы найти файл класса для Foo, а затем перейти к представлению встроенного класса Bar.
Я думаю, что настоящая причина того, что внутренние / вложенные классы имеют отдельные файлы классов, является исторической. IIRC, Java 1.0 не поддерживает вложенные или внутренние классы, и, следовательно, соответствующие форматы файлов классов не должны иметь с ними дело. Когда была создана Java 1.1 (поддерживающая внутренние / вложенные классы), Sun хотела, чтобы формат файла классов был совместим с файлами классов, созданными компилятором Java 1.0. Поэтому они решили реализовать внутренние / вложенные классы как отдельные файлы классов, используя зарезервированный символ «$
» в двоичном имени класса.
Вторая возможная причина заключается в том, что плоский формат упрощает загрузку классов по сравнению с гипотетическим встроенным форматом.
И, наконец, не было (и остается) неопровержимой причины НЕ использовать плоский формат файла. Возможно, это создает незначительные проблемы, когда какой-то программист хочет загрузить внутренние классы, используя Class.forName()
, но это довольно редкое явление ... и решение простое.