A ClassLoader
отвечает только за поиск и чтение файла класса и, при необходимости, связывает ProtectionDomain
с местоположением кода для поддержки мер безопасности.
Затем он передает байты одному изdefineClass
методы, которые наследует каждый загрузчик классов.Эти методы принимают байты файла класса либо в виде массива, либо ByteBuffer
, и выполняют всю магию, возвращая, наконец, Class
объект.
Эти Class
объекты в основном похожи на обычные объекты, но вы никогдасоздать их через new
;только JVM будет создавать экземпляры.Кроме того, JVM может связывать дополнительную информацию с этими объектами, которая не видна программисту приложения, смотрящему на объект Java.
То, что происходит в defineClass
, зависит от конкретной реализации.Но это типично, чтобы не хранить байты файла класса как есть.Скорее всего, они содержат информацию, не необходимую для выполнения, и требуемая информация может быть не в оптимальном формате для текущей платформы (например, порядок байтов и предпочтительное выравнивание данных).Кроме того, имеет смысл складывать одинаковые константы разных классов в одно хранилище.Так как данные класса должны быть проверены на достоверность в любом случае, имеет смысл объединить этот этап обработки с преобразованием данных во внутренний формат, более подходящий для последующей обработки.
Полная информация времени выполнения относительно класса по-прежнему распространяетсячерез кучу (например, экземпляр Class
и связанные с ним объекты Reflection) и область метода (например, код, информация о связях, внутренние структуры JVM и т. д.).Обратите внимание, что эти имена даны спецификацией, то есть куча Java определена как область памяти, содержащая все объекты Java , а область метода определена как хранилище метаданных .Поскольку это различие дается по определению , независимо от того, имеет ли оно значение для конкретной реализации (в конце концов, это просто ОЗУ), вы не увидите изменений, зависящих от реализации, в этой классификации.