Динамическая загрузка class является важной функцией виртуальной машины Java, потому что это предоставляет платформе Java возможность установить компоненты программного обеспечения во времени выполнения. У этого есть много уникальных характеристик. Прежде всего ленивая загрузка означает, что классы загружаются по требованию и в прошлый возможный момент. Во-вторых, динамическая загрузка class поддерживает безопасность типов виртуальной машины Java, добавляя разовые ссылкой проверки, которые заменяют определенные проверки на этапе выполнения и выполняются только однажды. Кроме того программисты могут определить свои собственные загрузчики class, которые, например, определяют удаленное расположение, от которого определенные классы загружаются, или присваивают соответствующие атрибуты безопасности им. Наконец, загрузчики class могут использоваться, чтобы обеспечить отдельные пространства имен для различных компонентов программного обеспечения. Например, браузер может загрузить апплеты из различных веб-страниц, используя отдельные загрузчики class, таким образом поддерживая степень изоляции между теми классами апплета. Фактически, эти апплеты могут содержать классы того же самого имени - эти классы обрабатываются как отличные типы виртуальной машиной Java.
Механизм загрузки class не является только центральным к динамическому характеру языка программирования Java. Это также играет критическую роль в обеспечении безопасности, потому что загрузчик class ответственен за определение местоположения и выборку файла class, консультацию с политикой безопасности, и определение объекта class с соответствующими полномочиями.
5.1 Иерархии классов Загрузчика класса
Загружая class, потому что могут быть многократные экземпляры объектов загрузчика class в одной виртуальной машине Java, важный вопрос состоит в том, как делают мы определяем который загрузчик class использовать. Java 2 SDK представили многократные классы загрузчика class, представляется, у которых есть отличные свойства, таким образом, другой важный вопрос состоит в том, какой загрузчик class мы должны использовать.
Корнем загрузчика class иерархия class является абстрактный class, названный java.lang. ClassLoder, первоначально определенный в JDK 1.0 и так как расширено. Класс java.security. SecureClassLoader, представленный в Java 2 SDK, v 1.2, является подклассом и конкретной реализацией абстрактного ClassLoder class. Класс java.net. URLClassLoader является подклассом SecureClassLoader.
Утилита по имени Апплетвивер использует частный class sun.applet. AppletClassLoader, чтобы загрузить апплеты. В JDK 1.0, AppletClassLoader является подклассом и конкретной реализацией ClassLoder. В Java 2 SDK это - подкласс URLClassLoader.
Создавая пользовательский загрузчик class class, можно разделить на подклассы от любого из вышеупомянутых классов загрузчика class, в зависимости от определенных потребностей пользовательского загрузчика class. Поскольку AppletClassLoader является частный class, определенный в пакете солнца *, он не поддерживается и подвержен изменениям, таким образом, нельзя разделить на подклассы от него.
5.2 Исконный Загрузчик Класса
Поскольку каждый class загружается его загрузчиком class, и каждый загрузчик самого class является class и должен быть загружен другим загрузчиком class, у нас, кажется, есть очевидная проблема цыпленка-и-яйца, то есть, куда первый загрузчик class прибывает из? Есть "исконный'' загрузчик class, который загружает процесс загрузки class. Исконный загрузчик class обычно пишется на родном языке, таком как C, и не проявляется в пределах контекста Java. Исконный загрузчик class часто загружает классы из локальной файловой системы зависимым от платформы способом.
Некоторые классы, такие как определенные в пакете Java *, важны для корректного функционирования системы времени выполнения и виртуальной машины Java. Они часто упоминаются как базовые классы. Из-за исторических причин, у всех таких классов есть загрузчик class, который является нулем. Этот нулевой загрузчик class является, возможно, единственным знаком существования исконного загрузчика class. Фактически, легче просто просмотреть нулевой загрузчик class как исконный загрузчик class.
Учитывая все классы в одной среде приложения Java, мы можем легко сформировать дерево загрузки class, чтобы отразить отношение загрузки class. Каждый class, который не является загрузчиком class, является вершиной. Родительский узел каждого class является своим загрузчиком class с нулевым загрузчиком class, являющимся корневым class. Такая структура является деревом, потому что не может быть циклов - загрузчик class не мог загрузить своего собственного предка загрузчик class.
5.3 Делегация Загрузчика класса
Когда один загрузчик class просят загрузить class, этот загрузчик class или загружает class непосредственно, или это может попросить, чтобы другой загрузчик class сделал так. Другими словами первый загрузчик class может делегировать к второму загрузчику class. Отношение делегации является виртуальным в том смысле, что оно не имеет никакого отношения к который загрузки загрузчика class который другой загрузчик class. Вместо этого отношение делегации формируется, когда объекты загрузчика class создаются, и в форме отношений отцов и детей. Однако, система загрузчик class является корневым предком делегации всех загрузчиков class. Забота должна быть проявлена, чтобы гарантировать, что отношение делегации не содержит циклы. Иначе, процесс делегации может ввести в бесконечный цикл.
5.4 Алгоритм Разрешения класса
Реализация по умолчанию Java 2 метода ClassLoder SDK для того, чтобы загрузить class ищет классы в следующем порядке:
Проверьте, был ли class уже загружен.
Если текущий загрузчик class сделал, чтобы указанная делегация породила, делегат в родителе, чтобы попытаться загрузить этот class. Если нет никакого родителя, делегата в исконном загрузчике class.
Вызовите настраиваемый метод, чтобы найти class в другом месте.
Здесь, первый шаг изучает локальный кэш загрузчика class (или его функциональный эквивалент, такой как глобальный кэш), чтобы видеть, соответствует ли загруженный class целевой class. Последний шаг обеспечивает способ настроить механизм для того, чтобы искать классы; таким образом пользовательский загрузчик class может переопределить этот метод, чтобы определить, как должен искаться class. Например, апплет загрузчик class может переопределить этот метод, чтобы вернуться к узлу апплета и попытаться определить местоположение файла class и загрузить это по сети.
Если в каком-либо шаге class располагается, это возвращается. Если class не находится, используя вышеупомянутые шаги, исключение ClassNotFound выдается.
Заметьте, что является критическим для безопасности типов, что тот же самый class не загружается не раз тем же самым загрузчиком class. Если class не среди уже загруженных, текущий загрузчик class пытается делегировать задачу к родительскому загрузчику class. Это может произойти рекурсивно. Это гарантирует, что соответствующий загрузчик class используется. Например, определяя местоположение системы class, процесс делегации продолжается до системы достигается загрузчик class.
Мы видели алгоритм делегации ранее. Но, учитывая имя какого-либо class, с какого загрузчика class мы запускаем в попытке загрузить class? Правила для того, чтобы определить загрузчик class являются следующим:
Загружая первый class приложения, новый экземпляр URLClassLoader используется.
Загружая первый class апплета, новый экземпляр AppletClassLoader используется.
Когда java.lang. Класс. ForName непосредственно вызывают, исконный загрузчик class используется.
Если запрос, чтобы загрузить class инициирован ссылкой на это от существующего class, загрузчик class для существующего class просят загрузить class.
Отметьте, что правила об использовании экземпляров URLClassLoader и AppletClassLoader имеют исключения и могут измениться в зависимости от определенной системной среды. Например, веб-браузер может хотеть снова использовать существующий AppletClassLoader, чтобы загрузить классы апплета из той же самой веб-страницы.
Из-за питания загрузчиков class, мы строго ограничиваем, кто может создать экземпляры загрузчика class. С другой стороны это является требуемым, чтобы обеспечить удобный механизм для приложений или апплетов, чтобы определить расположения URL и классы загрузки от них. Мы обеспечиваем статические методы, чтобы позволить любой программе создавать экземпляры URLClassLoader class, хотя не другие типы загрузчиков class.