Вход на хостинг
IT-новости
20.04.2016 iPhone 2017 года поместят в водонепроницаемый корпус из стекла
Линейка iPhone в новом году серьезно поменяется. В этом уверен аналитический исследователь Мин Чи Ку......
30.07.2015 Ищем уникальный контент для сайта
Ищем уникальный контент для сайта Без уникального контента Ваш сайт обречен на то, что его страницы......
метод invalidate, очищающий classesHash, просто не дал бы никакого эффекта. Виртуальная машина все равно извлекала бы класс из внутреннего кэша, пока мы не сменили бы экземпляр loader используемого загрузчика. А при использовании прямого вызова
loader.loadClass("Имя_класса")
метод invalidate, вместо ожидаемого «забывания» старых классов, привел бы к низкоуровневому исключению LinkageError.
Применения DynamicClassOverloader
Приведем несколько примеров ситуаций, где можно применить созданный нами загрузчик DynamicClassOverloader помимо решения поставленной нами главной задачи – загрузки измененных версий классов «на лету» без остановки основной программы.
Прежде всего напрашивается простейшее применение: профайлинг загрузки классов. С помощью параметра «-verbose:class» стандартной утилиты «java» можно проследить, какие классы загружаются в процессе работы. Но собственный загрузчик может сделать намного больше. Очень легко дополнить приведенный выше исходный код DynamicClassOverloader сбором любой статистики о загружаемых файлах: сколько классов различных пакетов загружается, сколько времени расходуется на загрузку классов, какие классы загружаются обычно в первую очередь и т. д.
DynamicClassOverloader можно использовать для загрузки классов из нестандартного каталога, не указанного в переменной CLASSPATH. Это требуется не так уж часто, но в некоторых ситуациях без этого сложно обойтись. Например, предположим, что вы пишете систему обработки документов, к которым могут прилагаться специальные Java-классы: как апплеты в веб-страницах или скрипты в документах Microsoft Word. Пользователь может работать с любым числом таких документов, расположенных где угодно в пределах своей файловой системы. Очевидно, для загрузки и исполнения таких классов, сопутствующих документу, стандартный набор путей из CLASSPATH окажется недостаточным.
Наконец, отдельные пространства имен, порождаемые экземплярами нашего загрузчика, из неудобного недостатка могут превратиться в ключевое достоинство. Обычно разработчики Java-классов избегают конфликтов имен своих классов благодаря стандартной системе именования пакетов, когда в имя пакета включается серия вложенных доменов Internet, соответствующих уникальному веб-сайту разработчика. Но если Java применяется в упрощенном виде – скажем, для реализации небольших скриптов конечными пользователями продукта – такая схема именования может оказаться чересчур обременительной. (Те же апплеты редко размещают в пакете. Часто пакет вообще не указывается, т.е. используется корневой package.) Наш загрузчик позволяет надежно изолировать друг от друга подобные простые классы, не нуждающиеся во взаимодействии друг с другом и разработанные, возможно, разными разработчиками. Если два класса загружены разными экземплярами DynamicClassOverloader, они могут спокойно иметь идентичное имя. Они «живут» в разных пространствах имен и не могут ничего «знать» друг о друге.
Заключение
Реализовав собственный загрузчик классов, мы действительно всерьез познакомились с миром отражений Java и много узнали о «внутренней кухне» виртуальной Java-машины. Конечно, это далеко не все.
Я не пытался написать исчерпывающее руководство. Я постарался предложить краткую экскурсию, позволяющую познакомиться с основными понятиями, технологиями и проблемами мира отражений Java и, я надеюсь, позволяющую почувствовать изящество и мощь этого чудесного языка. С помощью всего лишь около сотни строк исходного текста Java мы создали инструмент, позволивший существенно «подправить» поведение Java-машины и изменивший свойства самого языка Java.