Подтвердить что ты не робот

Кто сначала создает объект класса <?> Во время процесса загрузки класса?

В документации я нашел:

Объекты класса автоматически создаются виртуальной виртуальной машиной Java Virtual Загружается машина как классы и вызовы метода defineClass в загрузчике классов.

Я проверил исходный код, но не нашел место defineClass для вызова, например. из метода loadClass. Не могли бы вы показать мне, пожалуйста, кто и когда вызывается метод defineClass в соответствии с этой схемой:

схема

Изображение источник

4b9b3361

Ответ 1

Метод defineClass() вызывается во время вызова ClassLoader#loadClass(). Однако это не делается непосредственно в классе java.lang.ClassLoader, но в одном из его подклассов, например. в URLClassLoader#findClass().

Вызов ClassLoader#defineClass() завершается при вызове одного из собственных методов defineClass1() или defineClass2(). Реализации C этих методов можно найти в OpenJDK в src/share/native/java/lang/ClassLoader.c.

Ответ 2

java.lang.ClassLoader - такой большой класс. Используя ссылку GrepCode (которая для версии java 6-b14), вы можете найти в строке 267 общедоступный метод loadClass.

Этот метод вызывает защищенный метод loadClass в строке 308, и этот метод пытается загрузить ранее загруженный класс, используя:

  • findLoadedClass, который в конце вызывает Native методы,
  • Вызов parent.loadClass,
  • findBootstrapClass0 (собственный метод также), если нет parent,
  • И, наконец, findClass, если класс не найден.

Это важно сказать, потому что ClassLoader пытается повторно использовать уже загруженные кланы, имейте в виду.

Но где вызывается defineClass? Нет места из этого абстрактного класса, но если вы используете справочный инструмент из GrepCode и выполняете поиск, где он используется defineClass (см. Здесь результаты), вы будете найти много конкретных классов, которые в конце концов называет definClass.

Это не просто, некоторые из этих классов переопределяют defineClass, а другие называет свой собственный loadClass, который затем вызывает... и т.д., но, наконец, он вызывает defineClass.

Не забывайте, что defineClass of ClassLoader заканчивается одним из трех собственных методов, которые отвечают за магию JVM: defineClass0, defineClass1 и/или defineClass2

Изменить

Нативная функция defineClass0 вызывает Java_java_lang_ClassLoader_defineClass0 из ClassLoader.c и то же самое для 1 и 2 функций.

Эти функции создают необходимый класс, используя JVM_DefineClassWithSource, определенный в jvm.h и реализованный в openjdk\hotspot\src\share\vm\prims\jvm.cpp.

Этот последний файл определяет функцию jvm_define_class_common, которая в конце является функцией, которая создает необходимый класс. Наконец, эта функция вызывает JNIHandles::make_local, чтобы выделить класс. Вы можете увидеть код этой последней функции в openjdk\hotspot\src\share\vm\runtime\jniHandles.cpp

Надеюсь, он ответит на ваш вопрос.

Ответ 3

class NetworkClassLoader extends ClassLoader {
         String host;
         int port;

         public Class findClass(String name) {
             byte[] b = loadClassData(name);
             return defineClass(name, b, 0, b.length);
         }

         private byte[] loadClassData(String name) {
             // load the class data from the connection
              . . .
         }
     }