Загрузчики классов Java

Загрузчики классов JavaКомпилятор Java преобразует исходные инструкции в понятный для виртуальной машины Java код. Этот код сохраняется в файле класса с расширением .class. В каждом файле класса содержится код определения и реализации для только одного класса или интерфейса.

Далее все эти файлы классов интерпретируются программой, которая умеет преобразовывать набор инструкций виртуальной машины в машинные команды используемого компьютера.

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

Допустим, что выполнение программы начинается с файла MyProgram.class. Ниже описаны действия, которые выполняет виртуальная машина Java.

  1. В виртуальной машине имеется механизм загрузки файлов классов, например, путем считывания их с диска или копирования по сети. С помощью этого механизма загружается содержимое файла класса MyProgram.
  2. Если в классе MyProgram встречаются поля или объекты, ссылающиеся на классы других типов, тогда также еще загружаются и файлы этих классов. Процесс загрузки всех классов, от которых зависит данный класс, называется разрешением(resolving) класса.
  3. Затем виртуальная машина выполняет метод main() класса MyProgram. Этот метод является статическим, поэтому никаких экземпляров класса MyProgram создавать не требуется.
  4. Если для работы метода main() или метода, вызывающего из main(), требуются дополнительные классы, то загружаются соответствующие им файлы.

Следует отметить, что механизм загрузки классов использует не один, а несколько загрузчиков. С каждой программой Java применяется, по крайней мере, три загрузчика классов:

  • первичный загрузчик классов(bootstrap class loader);
  • расширенный загрузчик классов(extension class loader);
  • системный загрузчик классов(system class loader), иногда называемый прикладным загрузчиком классов(application class loader).

Первичный загрузчик классов загружает системные классы, как правило, из файла rt.jar. Он является неотъемлемой частью виртуальной машины и обычно реализуется на языке Си.

Первичному загрузчику классов не соответствует ни одного объекта ClassLoader. Например, показанный ниже вызов возвращает значение null:

Расширенный загрузчик классов загружает стандартное расширение из каталога jre/lib/ext. Если переместить файлы .jar в этот каталог, то расширенный загрузчик классов найдет в нем нужные классы расширения даже без указания пути к классам. Некоторые специалисты рекомендуют применять этот механизм, чтобы избежать путаницы с указанием пути к классам, но такой способ связан с определенными сложностями, которые описаны ниже.

Системный загрузчик классов загружает прикладные классы, которые размещаются в каталогах и файлах формата JAR/ZIP. Путь к классам должен быть указан с помощью переменной окружения CLASSPATH или параметра командной строки — classpath.

В системе, реализованной компанией Sun, расширенный и системный загрузчик реализуются на языке Java. Оба они представляют собой экземпляры класса URLClassLoader.

Помещать библиотеки в каталог jre/lib/ext нежелательно по следующей причине. Предположим, что вам понадобился один из классов этой библиотеки, который, в свою очередь, должен загружать класс, не являющийся системным или расширенным. Расширенный загрузчик классов не использует информация о пути к классам, устанавливаемую в переменной окружения CLASSPATH.

Этот факт необходимо учитывать, принимая решения об использовании каталога jre/lib/ext в качестве хранилища для своих классов.

Помимо всех уже перечисленных мест, классы еще также могут загружаться и из каталога jre/lib/endorsed. Такой механизм может применяться только для замены определенных стандартных библиотек Java. Подробнее об этом можете узнать по адресу http://java.sun.com/javase/6/docs/technotes/guides/standards/index.html