Trình tải lớp Java là gì?


174

Trong một vài câu đơn giản, Java ClassLoader là gì, khi nào nó được sử dụng và tại sao?

OK, tôi đọc một bài viết wiki. ClassLoader tải các lớp. ĐỒNG Ý. Vì vậy, nếu tôi bao gồm các tệp jar và nhập, ClassLoader thực hiện công việc.

Tại sao tôi phải bận tâm với ClassLoader này? Tôi chưa bao giờ sử dụng nó và không biết nó tồn tại.

Câu hỏi là, tại sao lớp ClassLoader tồn tại? Và ngoài ra, làm thế nào để bạn sử dụng nó trong thực tế? (Trường hợp tồn tại, tôi biết.)


Bạn sẽ nhận được kết quả tốt hơn nếu bạn thu hẹp câu hỏi của mình, ví dụ: bằng cách chỉ ra một phần cụ thể mà bạn không hiểu, nó liên quan đến một số ngôn ngữ khác mà bạn quen thuộc, v.v.
JRL

75
Đây là một câu hỏi hoàn toàn hợp lý, khi nhìn từ góc độ của một người đang tìm kiếm một vài câu đơn giản để giải thích khái niệm này
oxbow_lakes

Video này có thể được quan tâm: Bạn có thực sự có Trình tải lớp không?
asmaier

Câu trả lời:


231

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.ClassLoaderlà 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 .


47

Hầu hết các nhà phát triển Java sẽ không bao giờ cần sử dụng rõ ràng các trình nạp lớp (ngoại trừ tải tài nguyên để nó vẫn hoạt động khi chúng được gói trong JAR), chứ đừng nói là tự viết.

Trình tải lớp được sử dụng trong các hệ thống lớn và ứng dụng máy chủ để thực hiện những việc như:

  • Mô đun hóa một hệ thống và tải, dỡ và cập nhật các mô-đun trong thời gian chạy
  • Sử dụng song song các phiên bản khác nhau của thư viện API (ví dụ: trình phân tích cú pháp XML)
  • Cô lập các ứng dụng khác nhau chạy trong cùng một JVM (đảm bảo chúng không can thiệp lẫn nhau, ví dụ như thông qua các biến tĩnh)

29

Câu hỏi là "Tại sao một người nên làm phiền lớp ClassLoader này"?

Chà, chủ yếu là để bạn có thể sửa chữa mọi thứ nếu chúng gặp trục trặc :-).

Điều đó đúng, miễn là bạn chỉ cần viết một ứng dụng, biên dịch nó thành JAR và có thể bao gồm một vài JAR thư viện bổ sung, bạn không cần biết về trình tải lớp, nó sẽ chỉ hoạt động.

Tuy nhiên, thật hữu ích khi biết một chút về trình tải lớp và tải lớp để hiểu rõ hơn những gì diễn ra sau hậu trường. Ví dụ, "bộ khởi tạo tĩnh" sẽ chạy khi một lớp được tải, vì vậy để hiểu khi nào chúng sẽ chạy, bạn cần biết trình tải lớp quyết định khi nào tải chúng.

Ngoài ra .. làm thế nào để bạn sử dụng nó trong thực tế?

Đối với những trường hợp đơn giản, bạn không cần chúng. Tuy nhiên, nếu bạn cần tải mã động khi chạy với kiểm soát rõ ràng xuất phát từ đâu (ví dụ tải qua mạng, tải plugin không có sẵn tại thời gian biên dịch, v.v.), bạn có thể cần phải làm nhiều hơn. Sau đó, bạn có thể ví dụ viết trình nạp lớp của riêng bạn. Xem các câu trả lời khác cho các liên kết.


14

ClassLoadertrong Java là một lớp được sử dụng để tải các tệp lớp trong Java. Mã Java được biên dịch thành tệp lớp bởi javactrình biên dịch và JVM thực thi chương trình Java, bằng cách thực thi mã byte được ghi trong tệp lớp.

ClassLoader chịu trách nhiệm tải các tệp lớp từ hệ thống tệp, mạng hoặc bất kỳ nguồn nào khác. Có ba trình nạp lớp mặc định được sử dụng trong Java, Bootstrap , Tiện ích mở rộngHệ thống hoặc Trình tải lớp ứng dụng .

Trình tải lớp


Cách ClassLoader hoạt động

## Tương tác ClassLoader với JVM nhập mô tả hình ảnh ở đây

Thêm @: how-classloader-works-in-java.html


6

Trình tải lớp là một thành phần chức năng của JVM, tải dữ liệu lớp từ tệp '. Class' hoặc từ qua mạng vào Vùng phương thức trong Heap.

Trông giống như một phần không thể thiếu của JVM, nhưng với tư cách là người dùng java cuối, tại sao tôi phải quan tâm? Đây là lý do tại sao:

Mỗi trình nạp lớp có không gian tên riêng và các lớp được gọi bởi trình nạp lớp cụ thể vào không gian tên của nó.

Các lớp được gọi bởi hai trình nạp lớp khác nhau sẽ không có khả năng hiển thị lẫn nhau, dẫn đến tăng cường bảo mật.

Cơ chế ủy nhiệm lớp cha mẹ của trình nạp lớp đảm bảo các lớp api java không bao giờ có thể bị hack bởi mã trái phép.

Để biết chi tiết xem tại đây


1

Trình nạp lớp được phân cấp. Các lớp được giới thiệu cho JVM khi chúng được tham chiếu theo tên trong một lớp đã chạy trong JVM.

Làm thế nào các lớp đầu tiên được tải?
Lớp đầu tiên được tải với sự trợ giúp của static main()phương thức được khai báo trong lớp của bạn. Tất cả các lớp được tải sau đó được tải bởi các lớp đã được tải và đang chạy.

Một trình nạp lớp tạo ra một không gian tên. Tất cả JVM bao gồm ít nhất một trình nạp lớp được nhúng trong JVM được gọi là trình nạp lớp nguyên thủy (hoặc bootstrap) . Đó là một điều, và chúng ta sẽ xem xét các trình nạp lớp không nguyên thủy. JVM có các hook trong đó để cho phép các trình nạp lớp do người dùng định nghĩa được sử dụng thay cho trình nạp lớp nguyên thủy. Dưới đây là các trình nạp lớp được tạo bởi JVM.

Bootstrap (nguyên thủy) Trình nạp lớp này không tải lại được. Tải các lớp bên trong JDK, các gói java. * (Thường tải rt.jar và i18n.jar). Extesions Trình nạp lớp này không tải lại được. Tải các tệp jar từ thư mục tiện ích mở rộng JDK (thường là lib / ext của JRE). Hệ thống Trình nạp lớp này không tải lại được. Tải các lớp từ đường dẫn lớp hệ thống.

http://www.sbalasani.com/2015/01/java- class-loaders.html


1

Khi bạn hỏi tại sao lớp ClassLoader tồn tại, lý do khá đơn giản - đó là lớp chịu trách nhiệm tìm và tải các tệp lớp trong thời gian chạy .

Hãy giải thích nó.

Trong JVM, mọi Class được tải bởi một số thể hiện của java.lang.ClassLoader. Bất cứ khi nào một JVM mới được khởi động bởi bạn java <classname>, lệnh khởi chạy chương trình Java thông thường , bước đầu tiên là tải tất cả các lớp khóa trong bộ nhớ cần thiết để hoạt động đúng nhưjava.lang.Object các lớp thời gian chạy khác ( rt.jar).

Bây giờ, thực sự có 3 phần cho ClassLoader:

  • Các BootstrapClassLoader trách nhiệm làm cho các lớp này có sẵn tức là tải các lớp này trong bộ nhớ.

  • Nhiệm vụ tiếp theo là tải bất kỳ thư viện / JAR bên ngoài nào vào bộ nhớ để ứng dụng hoạt động đúng. CácExtClassLoader trách nhiệm cho nhiệm vụ này. Trình tải lớp này chịu trách nhiệm tải tất cả các tệp .jar được đề cập trong đường dẫn java.ext.dirs.

  • Trình nạp lớp quan trọng thứ ba và chính là AppClassLoader. Trình tải lớp ứng dụng chịu trách nhiệm tải các tệp lớp được đề cập trong thuộc tính hệ thống java. Class.path.

Cũng cần lưu ý rằng việc triển khai ClassLoader mặc định có thể bị ghi đè cho phép bạn tùy chỉnh JVM theo những cách hữu ích và thú vị, cho phép bạn xác định lại hoàn toàn cách các tệp lớp được đưa vào hệ thống.

nhập mô tả hình ảnh ở đây

Hãy xem thử để tìm hiểu thêm về Trình tải lớp Java .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.