2015-12-03 16 views
17

Trong documentation tôi thấy:Ai trước hết tạo đối tượng Class <?> trong quá trình tải lớp?

đối tượng Class được xây dựng tự động bằng Java Virtual Machine như các lớp được nạp và cuộc gọi đến các phương pháp defineClass trong class loader.

Tôi đã kiểm tra the source code, nhưng không tìm thấy địa điểm defineClass được gọi là ví dụ: từ phương thức loadClass. bạn có thể chỉ cho tôi, xin vui lòng, ai và khi gọi defineClass phương pháp theo sơ đồ này:

scheme

Hình source

+1

Khi bạn đang giao dịch với JVM internals (magic!), Một nghi ngờ tốt là mọi thứ đang xảy ra trong mã gốc (C/C++/asm). – Nayuki

+0

Chắc chắn nó có thể được, nhưng câu hỏi là: khi nào nó (Class đối tượng xuất hiện) xảy ra? Ngôn ngữ thực hiện không quan trọng –

Trả lời

10

Phương pháp defineClass() được gọi trong thời gian gọi của ClassLoader#loadClass(). Tuy nhiên, điều này không được thực hiện trực tiếp trong lớp java.lang.ClassLoader nhưng thuộc một trong các lớp con của nó, ví dụ: trong URLClassLoader#findClass().

Các cuộc gọi đến ClassLoader#defineClass() kết thúc trong một cuộc gọi đến một trong những mẹ đẻ phương pháp defineClass1() hoặc defineClass2(). Việc triển khai C của các phương thức này có thể được tìm thấy trong OpenJDK trong src/share/native/java/lang/ClassLoader.c.

5

java.lang.ClassLoader là một lớp học lớn như vậy. Sử dụng liên kết GrepCode của bạn (dành cho java 6-b14 phiên bản) bạn có thể tìm thấy tại dòng 267 phương thức công khai loadClass.

Phương pháp này, gọi là bảo vệ loadClass phương pháp tại dòng 308 và phương pháp này cố gắng tải một lớp được nạp previosly sử dụng:

  • findLoadedClass mà trong đầu gọi các phương thức bản địa,
  • Calling parent.loadClass,
  • findBootstrapClass0 (phương pháp gốc cũng) nếu không có parent,
  • Và cuối cùng là findClass nếu không tìm thấy lớp học nào.

Điều này rất quan trọng để nói, vì ClassLoader cố gắng sử dụng lại các bản sao đã tải, hãy ghi nhớ.

Nhưng, ở đâu được gọi là defineClass? Không có nơi nào từ lớp trừu tượng này, nhưng nếu bạn sử dụng công cụ tham khảo từ GrepCode và tìm kiếm nơi nó được sử dụng defineClass (see here results), bạn sẽ tìm thấy rất nhiều lớp cụ thể mà cuối cùng gọi definClass.

Không đơn giản, một số trong các lớp này ghi đè defineClass trong khi các trường khác gọi số loadClass của riêng chúng, sau đó gọi ... và cuối cùng, gọi số defineClass.

Đừng quên rằng defineClass của ClassLoader kết thúc theo một trong ba phương pháp tự nhiên mà là trách nhiệm của JVM diệu: defineClass0, defineClass1 và/hoặc defineClass2

Sửa

chức năng Native defineClass0 cuộc gọi Java_java_lang_ClassLoader_defineClass0 từ ClassLoader.c và tương tự cho 1 và 2 chức năng.

Chức năng này tạo lớp bắt buộc sử dụng JVM_DefineClassWithSource được xác định trong jvm.h và được triển khai trong openjdk\hotspot\src\share\vm\prims\jvm.cpp.

Tệp cuối cùng này xác định hàm jvm_define_class_common mà cuối cùng là hàm tạo lớp bắt buộc. Cuối cùng, hàm này gọi JNIHandles::make_local để cấp phát lớp. Bạn có thể xem mã của hàm cuối cùng này trong openjdk\hotspot\src\share\vm\runtime\jniHandles.cpp

Hy vọng nó sẽ trả lời câu hỏi của bạn.

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

Đây là giải nén fomr Oracle dosumentation.defineClass là một phương thức của ClassLoader để chuyển đổi một mảng các byte thành một thể hiện của lớp Class. Tôi hy vọng nó sẽ giúp – Hiren

Các vấn đề liên quan