Внутренние классы — это функция языка Java, а не функция JVM. То есть компиляторы Java «сглаживают» структуру классов, поэтому JVM просто видит обычные классы, обычно с $
в именах. В этом случае будут классы test.sample.A
и test.sample.A$B
(последний является полным именем B
). Анонимные внутренние классы получают имена, определяемые компилятором, обычно начинающиеся с 1
и увеличивающиеся: например, test.sample.A$6
. Компилятор может добавлять методы с такими именами, как access$200
, чтобы позволить охватывающему классу и внутреннему классу получать доступ к закрытым членам друг друга. (Обратите внимание, что $
разрешено, хотя и не рекомендуется, в именах определяемых пользователем классов и методов, поэтому наличие $
в имени не означает, что оно сгенерировано компилятором; для этого есть Синтетический атрибут и бит-модификатор ACC_SYNTHETIC, отображаемый отражательно через такие методы, как Class.isSynthetic()< /а>.)
JVM загружает эти классы точно так же, как и любой другой класс, обычно ища файл test/sample/A$B.class
в каком-нибудь JAR-файле, но также, возможно, загружая их по сети, генерируя их на лету с помощью библиотеки для обработки байт-кода и т. д.
При создании файлов классов, которые ссылаются на внутренний класс (определение, содержание или просто использование), компиляторы Java выдают InnerClasses, определяющие отношения включения, для помощи в раздельной компиляции и отражении (Class.getDeclaringClass() и Class.getEnclosingClass()). Файлы классов для классов, определенных внутри метода, также содержат EnclosingMethod, относящийся к методу включения, для отражения (Class.getEnclosingMethod() и Class.getEnclosingConstructor()). Однако JVM проверяет синтаксическую правильность этих атрибутов только во время загрузки и компоновки; о несоответствиях не сообщается до тех пор, пока не будут фактически вызваны отражающие методы.
person
Jeffrey Bosboom
schedule
04.07.2014