Почему Java генерирует несколько файлов .class при компиляции? - PullRequest
8 голосов
/ 27 января 2010

В Java при компиляции мы получаем файл .class для каждого класса (включая вложенные классы и интерфейсы), определенного в исходном файле.

В чем причина создания нескольких файлов .class?
Это для упрощения повторного использования класса?
Почему бы не сгенерировать один .class для одного файла .java?

Ответы [ 3 ]

13 голосов
/ 27 января 2010

JVM должна быть в состоянии найти код для данного класса, учитывая его имя. Если между исходным именем файла и именем файла кода нет никакой потенциальной связи, и вы хотите, чтобы имя файла кода основывалось на имени файла source , как вы ожидаете, что оно загрузит код?

В качестве примера: предположим, я должен был скомпилировать Foo.java, который содержит класс Bar.

Затем другой класс ссылается на Bar, поэтому JVM нужен код для него ... как бы вы предположили, что он находит файл?

Обратите внимание, что в .NET есть отдельная единица развертывания, называемая сборка - и ссылка на тип также включает имя сборки, но это немного отличается от того, что вы предлагали.

7 голосов
/ 27 января 2010

В ответ на риторический вопрос @Jon Skeet:

Затем другой класс ссылается на Bar, поэтому JVM нужен код для него ... как бы вы предположили, что он находит файл?

Предположим (гипотетически), что формат файла классов Java представляет вложенные / внутренние классы, встраивая их в файл классов для самого внешнего класса. Двоичное имя для бара: "Lsome/pkg/Foo$Bar;". Загрузчик классов может разделить имя на символ "$", использовать первую часть, чтобы найти файл класса для Foo, а затем перейти к представлению встроенного класса Bar.

Я думаю, что настоящая причина того, что внутренние / вложенные классы имеют отдельные файлы классов, является исторической. IIRC, Java 1.0 не поддерживает вложенные или внутренние классы, и, следовательно, соответствующие форматы файлов классов не должны иметь с ними дело. Когда была создана Java 1.1 (поддерживающая внутренние / вложенные классы), Sun хотела, чтобы формат файла классов был совместим с файлами классов, созданными компилятором Java 1.0. Поэтому они решили реализовать внутренние / вложенные классы как отдельные файлы классов, используя зарезервированный символ «$» в двоичном имени класса.

Вторая возможная причина заключается в том, что плоский формат упрощает загрузку классов по сравнению с гипотетическим встроенным форматом.

И, наконец, не было (и остается) неопровержимой причины НЕ использовать плоский формат файла. Возможно, это создает незначительные проблемы, когда какой-то программист хочет загрузить внутренние классы, используя Class.forName(), но это довольно редкое явление ... и решение простое.

2 голосов
/ 27 января 2010

Это проектное решение относительно модуля компиляции, принятое разработчиками. Скомпилированные классы обычно объединяются в jar-файл.

Извлечение из Спецификация языка Java

7.3 Единицы компиляции CompilationUnit - это символ цели (§2.1) для синтаксической грамматики (§2.3) Java программы.

Типы, объявленные в разных единицах компиляции, могут циклически зависеть друг от друга. Компилятор Java должен организовать компиляцию всех таких типов одновременно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...