[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"question-java-core-rasskazhite-pro-klassy-zagruzchiki-i-pro-dinamicheskuyu-zagruzku-klassov":3},{"id":4,"slug":5,"topicId":6,"topicSlug":7,"topicName":8,"topicEmoji":9,"question":10,"answer":11,"codeLang":12,"codeSrc":12,"important":12,"commonMistakes":12,"modernUsage":12,"difficulty":13,"tags":14,"related":19,"progress":20,"seo":21},77,"rasskazhite-pro-klassy-zagruzchiki-i-pro-dinamicheskuyu-zagruzku-klassov",2,"java-core","Java Core","☕","Расскажите про классы-загрузчики и про динамическую загрузку классов.","Основа работы с классами в Java — классы-загрузчики, обычные Java-объекты, предоставляющие интерфейс для поиска и создания объекта класса по его имени во время работы приложения.\n\nВ начале работы программы создается 3 основных загрузчика классов:\n\n+ **базовый загрузчик (bootstrap\u002Fprimordial)**. Загружает основные системные и внутренние классы JDK (Core API - пакеты `java.*` (`rt.jar` и `i18n.jar`) . Важно заметить, что базовый загрузчик является «Изначальным» или «Корневым» и частью JVM, вследствие чего его нельзя создать внутри кода программы.\n+ **загрузчик расширений (extention)**. Загружает различные пакеты расширений, которые располагаются в директории `\u003CJAVA_HOME>\u002Flib\u002Fext` или другой директории, описанной в системном параметре `java.ext.dirs`. Это позволяет обновлять и добавлять новые расширения без необходимости модифицировать настройки используемых приложений. Загрузчик расширений реализован классом `sun.misc.Launcher$ExtClassLoader`.\n+ **системный загрузчик (system\u002Fapplication)**. Загружает классы, пути к которым указаны в переменной окружения `CLASSPATH` или пути, которые указаны в командной строке запуска JVM после ключей `-classpath` или `-cp`. Системный загрузчик реализован классом `sun.misc.Launcher$AppClassLoader`.\n\nЗагрузчики классов являются иерархическими: каждый из них (кроме базового) имеет родительский загрузчик и в большинстве случаев, перед тем как попробовать загрузить класс самостоятельно, он посылает вначале запрос родительскому загрузчику загрузить указанный класс. Такое делегирование позволяет загружать классы тем загрузчиком, который находится ближе всего к базовому в иерархии делегирования. Как следствие поиск классов будет происходить в источниках в порядке их доверия: сначала в библиотеке Core API, потом в папке расширений, потом в локальных файлах `CLASSPATH`.\n\nПроцесс загрузки класса состоит из трех частей:\n\n+ Loading – на этой фазе происходит поиск и физическая загрузка файла класса в определенном источнике (в зависимости от загрузчика). Этот процесс определяет базовое представление класса в памяти. На этом этапе такие понятия как «методы», «поля» и т.д. пока не известны.\n+ Linking – процесс, который может быть разбит на 3 части:\n    + Bytecode verification – проверка байт-кода на соответствие требованиям, определенным в спецификации JVM.\n    + Class preparation – создание и инициализация необходимых структур, используемых для представления полей, методов, реализованных интерфейсов и т.п., определенных в загружаемом классе.\n    + Resolving – загрузка набора классов, на которые ссылается загружаемый класс.\n+ Initialization – вызов статических блоков инициализации и присваивание полям класса значений по умолчанию.\n\nДинамическая загрузка классов в Java имеет ряд особенностей:\n\n+ отложенная (lazy) загрузка и связывание классов. Загрузка классов производится только при необходимости, что позволяет экономить ресурсы и распределять нагрузку.\n+ проверка корректности загружаемого кода (type safeness). Все действия связанные с контролем использования типов производятся только во время загрузки класса, позволяя избежать дополнительной нагрузки во время выполнения кода.\n+ программируемая загрузка. Пользовательский загрузчик полностью контролирует процесс получения запрошенного класса — самому ли искать байт-код и создавать класс или делегировать создание другому загрузчику. Дополнительно существует возможность выставлять различные атрибуты безопасности для загружаемых классов, позволяя таким образом работать с кодом из ненадежных источников.\n+ множественные пространства имен. Каждый загрузчик имеет своё пространство имён для создаваемых классов. Соответственно, классы, загруженные двумя различными загрузчиками на основе общего байт-кода, в системе будут различаться.\n\nСуществует несколько способов инициировать загрузку требуемого класса:\n\n+ явный: вызов `ClassLoader.loadClass()` или `Class.forName()` (по умолчанию используется загрузчик, создавший текущий класс, но есть возможность и явного указания загрузчика);\n+ неявный: когда для дальнейшей работы приложения требуется ранее не использованный класс, JVM инициирует его загрузку.","","middle",[15,16,17,18],"jvm","core","classloader","dynamic-loading",[],null,{"title":22,"description":23,"ogTitle":22,"ogDescription":24,"keywords":25,"schemaAnswer":31,"featuredSnippetReady":32},"Классы-загрузчики и динамическая загрузка классов в Java — Gymterview","Классы-загрузчики в Java: bootstrap, extension, system. Процесс загрузки классов (loading, linking, initialization) и динамическая загрузка.","Иерархия загрузчиков классов в Java: bootstrap, extension, system. Процесс загрузки и динамическая загрузка.",[26,27,28,29,30],"ClassLoader Java","загрузчик классов","bootstrap classloader","динамическая загрузка классов","Class.forName","В начале работы программы создаются 3 основных загрузчика: базовый (bootstrap) — загружает Core API, загрузчик расширений (extension) — загружает пакеты из lib\u002Fext, системный (application) — загружает классы из CLASSPATH. Загрузчики иерархические: каждый делегирует запрос родительскому. Процесс загрузки включает: Loading (поиск и загрузка файла), Linking (верификация, подготовка, разрешение зависимостей), Initialization (вызов статических блоков). Загрузку можно инициировать явно (ClassLoader.loadClass(), Class.forName()) или неявно.",true]