Как загрузчик классов jvm загружает класс, определенный внутри другого класса?
Как JVM загружает класс, определенный внутри другого класса?
Пример: допустим, есть класс B, который определен внутри класса A
package test.sample;
Class A {
// some instructions
Class B {
// few more instructions
}
}
В этом случае,
- Как загрузчик классов загружает класс B? (т.е. как он идентифицирует класс B?)
- Какое будет полное имя класса B?
1 ответ
Внутренние классы - это функция языка Java, а не функция JVM. То есть компиляторы Java "выравнивают" структуру классов, поэтому JVM видит обычные классы, обычно с $
в их именах. В этом случае были бы классы test.sample.A
а также test.sample.A$B
(последний является полностью определенным именем B
). Анонимные внутренние классы получают имена, определенные компилятором, обычно начиная с 1
и считать: test.sample.A$6
, например. Компилятор может добавлять методы с такими именами, как access$200
разрешить включающему классу и внутреннему классу доступ к закрытым членам друг друга. (Обратите внимание, что $
допустимо, хотя и не рекомендуется, в пользовательских именах классов и методов, поэтому наличие $
имя не означает, что оно генерируется компилятором; для этого есть атрибут Synthetic и бит модификатора ACC_SYNTHETIC, отражаемый с помощью методов типа Class.isSynthetic ()).
JVM загружает эти классы, как и любой другой класс, обычно ищет файл test/sample/A$B.class
в некотором файле JAR, но также возможно загружать их по сети, генерируя их на лету с помощью библиотеки манипулирования байт-кодом и т. д.
При создании файлов классов, которые ссылаются на внутренний класс ( определяющий, содержащий или просто использующий), компиляторы Java испускают атрибуты InnerClasses, определяющие отношения включения, для помощи отдельной компиляции и отражению ( Class.getDeclaringClass () и Class.getEnclosingClass ()), Файлы классов для классов, определенных внутри метода, также содержат атрибут EnclosingMethod, относящийся к методу включения, для отражения (Class.getEnclosingMethod () и Class.getEnclosingConstructor ()). Однако эти атрибуты проверяются только на синтаксическую корректность JVM во время загрузки и связывания; о несоответствиях не сообщается до тех пор, пока не будут вызваны отражательные методы.