2015-12-03 2 views
17

В documentation я нашел:Кто во-первых создает объект класса <?> во время процесса загрузки класса?

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

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

scheme

Изображение source

+1

Когда вы имеете дело с внутренностями JVM (магия!), Хорошее подозрение в том, что все происходит в собственном коде (C/C++/asm). – Nayuki

+0

Уверен, что это может быть, но вопрос: когда это происходит (объект класса)? Язык реализации не имеет значения. –

ответ

10

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

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

5

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

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

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

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

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

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

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

Edit

Native функции 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

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

1
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 
       . . . 
     } 
    } 
+0

Это извлечение fomr. Oracle dosumentation.defineClass - это метод класса ClassLoader, который преобразует массив байтов в экземпляр класса Class. Надеюсь, это поможет – Hiren