Lấy từ hướng dẫn tốt đẹp này từ Sun:
Động lực
Các ứng dụng được viết bằng các ngôn ngữ lập trình được biên dịch tĩnh, chẳng hạn như C và C ++, được biên dịch thành các hướng dẫn riêng, dành riêng cho máy và được lưu dưới dạng tệp thực thi. Quá trình kết hợp mã thành mã gốc thực thi được gọi là liên kết - việc hợp nhất mã được biên dịch riêng với mã thư viện dùng chung để tạo ra một ứng dụng thực thi. Điều này khác với các ngôn ngữ lập trình được biên dịch động như Java. Trong Java, các tệp. Class được tạo bởi trình biên dịch Java vẫn giữ nguyên trạng thái cho đến khi được tải vào Máy ảo Java (JVM) - nói cách khác, quá trình liên kết được JVM thực hiện khi chạy. Các lớp được tải vào JVM trên cơ sở 'khi cần thiết'. Và khi một lớp được tải phụ thuộc vào một lớp khác, thì lớp đó cũng được tải.
Khi một ứng dụng Java được khởi chạy, lớp đầu tiên chạy (hoặc điểm vào trong ứng dụng) là lớp có phương thức void static static được gọi là main (). Lớp này thường có các tham chiếu đến các lớp khác và tất cả các nỗ lực để tải các lớp được tham chiếu được thực hiện bởi trình nạp lớp.
Để có được cảm giác về lớp đệ quy này cũng như ý tưởng tải lớp nói chung, hãy xem xét lớp đơn giản sau:
public class HelloApp {
public static void main(String argv[]) {
System.out.println("Aloha! Hello and Bye");
}
}
Nếu bạn chạy lớp này chỉ định tùy chọn dòng lệnh -verbose: class, để nó in những lớp nào đang được tải, bạn sẽ nhận được một đầu ra trông như sau. Lưu ý rằng đây chỉ là một đầu ra một phần vì danh sách quá dài để hiển thị ở đây.
prmpt>java -verbose:class HelloApp
[Opened C:\Program Files\Java\jre1.5.0\lib\rt.jar]
[Opened C:\Program Files\Java\jre1.5.0\lib\jsse.jar]
[Opened C:\Program Files\Java\jre1.5.0\lib\jce.jar]
[Opened C:\Program Files\Java\jre1.5.0\lib\charsets.jar]
[Loaded java.lang.Object from shared objects file]
[Loaded java.io.Serializable from shared objects file]
[Loaded java.lang.Comparable from shared objects file]
[Loaded java.lang.CharSequence from shared objects file]
[Loaded java.lang.String from shared objects file]
[Loaded java.lang.reflect.GenericDeclaration from shared objects file]
[Loaded java.lang.reflect.Type from shared objects file]
[Loaded java.lang.reflect.AnnotatedElement from shared objects file]
[Loaded java.lang.Class from shared objects file]
[Loaded java.lang.Cloneable from shared objects file]
[Loaded java.lang.ClassLoader from shared objects file]
[Loaded java.lang.System from shared objects file]
[Loaded java.lang.Throwable from shared objects file]
.
.
.
[Loaded java.security.BasicPermissionCollection from shared objects file]
[Loaded java.security.Principal from shared objects file]
[Loaded java.security.cert.Certificate from shared objects file]
[Loaded HelloApp from file:/C:/classes/]
Aloha! Hello and Bye
[Loaded java.lang.Shutdown from shared objects file]
[Loaded java.lang.Shutdown$Lock from shared objects file]
Như bạn có thể thấy, các lớp thời gian chạy Java được yêu cầu bởi lớp ứng dụng (HelloApp) được tải trước tiên.
Trình tải lớp trong Nền tảng Java 2
Ngôn ngữ lập trình Java tiếp tục phát triển để làm cho cuộc sống của các nhà phát triển ứng dụng dễ dàng hơn mỗi ngày. Điều này được thực hiện bằng cách cung cấp các API giúp đơn giản hóa cuộc sống của bạn bằng cách cho phép bạn tập trung vào logic kinh doanh thay vì chi tiết triển khai các cơ chế cơ bản. Điều này thể hiện rõ qua sự thay đổi gần đây của J2SE 1.5 thành J2SE 5.0 nhằm phản ánh sự trưởng thành của nền tảng Java.
Kể từ JDK 1.2, trình nạp lớp bootstrap được tích hợp vào JVM chịu trách nhiệm tải các lớp của thời gian chạy Java. Trình tải lớp này chỉ tải các lớp được tìm thấy trong đường dẫn khởi động và vì đây là các lớp đáng tin cậy, quá trình xác nhận không được thực hiện như đối với các lớp không tin cậy. Ngoài trình nạp lớp bootstrap, JVM còn có trình nạp lớp mở rộng chịu trách nhiệm tải các lớp từ API mở rộng tiêu chuẩn và trình nạp lớp hệ thống tải các lớp từ đường dẫn lớp chung cũng như các lớp ứng dụng của bạn.
Vì có nhiều hơn một trình nạp lớp, chúng được biểu diễn trong một cây có gốc là trình nạp lớp bootstrap. Mỗi trình nạp lớp có một tham chiếu đến trình nạp lớp cha của nó. Khi một trình nạp lớp được yêu cầu tải một lớp, nó sẽ hỏi trình tải lớp cha của nó trước khi cố gắng tự tải mục đó. Phụ huynh lần lượt hỏi ý kiến cha mẹ của mình, v.v. Vì vậy, chỉ sau khi tất cả các trình nạp lớp tổ tiên không thể tìm thấy lớp mà trình nạp lớp hiện tại có liên quan. Nói cách khác, một mô hình đoàn được sử dụng.
Lớp java.lang.ClassLoader
Đây java.lang.ClassLoader
là một lớp trừu tượng có thể được phân lớp bởi các ứng dụng cần mở rộng cách thức mà JVM tải động các lớp. Các hàm tạo trong java.lang.ClassLoader
(và các lớp con của nó) cho phép bạn chỉ định cha mẹ khi bạn khởi tạo trình nạp lớp mới. Nếu bạn không chỉ định rõ ràng cha mẹ, trình nạp lớp hệ thống của máy ảo sẽ được chỉ định là cha mẹ mặc định. Nói cách khác, lớp ClassLoader sử dụng mô hình ủy quyền để tìm kiếm các lớp và tài nguyên. Do đó, mỗi phiên bản của ClassLoader có trình tải lớp cha liên kết, do đó khi được yêu cầu tìm một lớp hoặc tài nguyên, tác vụ được ủy quyền cho trình nạp lớp cha của nó trước khi cố gắng tìm lớp hoặc tài nguyên của chính nó. Các loadClass()
phương pháp của ClassLoader thực hiện các nhiệm vụ sau, theo thứ tự, khi được kêu gọi để nạp một lớp:
Nếu một lớp đã được tải, nó sẽ trả về nó. Mặt khác, nó ủy nhiệm việc tìm kiếm lớp mới cho trình nạp lớp cha. Nếu trình nạp lớp cha không tìm thấy lớp, hãy loadClass()
gọi phương thức findClass()
để tìm và tải lớp. Các finalClass()
tìm kiếm phương pháp cho các lớp trong bộ nạp lớp hiện tại nếu lớp không được tìm thấy bởi các bộ nạp lớp cha mẹ.
Có nhiều hơn trong bài viết gốc, cũng cho bạn thấy cách triển khai các trình tải lớp mạng của riêng bạn, câu trả lời cho câu hỏi của bạn là tại sao (và làm thế nào). Xem thêm các tài liệu API .