Кто сначала создает объект класса <?> Во время процесса загрузки класса?
В документации я нашел:
Объекты класса автоматически создаются виртуальной виртуальной машиной Java Virtual Загружается машина как классы и вызовы метода defineClass в загрузчике классов.
Я проверил исходный код, но не нашел место defineClass
для вызова, например. из метода loadClass.
Не могли бы вы показать мне, пожалуйста, кто и когда вызывается метод defineClass
в соответствии с этой схемой:
![схема]()
Изображение источник
Ответы
Ответ 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
. . .
}
}