2009-11-29 29 views
15

Giả sử một codebase java có một gói có tên là "com.example".Có cách nào để buộc một trình nạp lớp tải gói ngay cả khi không có lớp nào của nó được tải?

Khi chạy, chúng tôi có thể nhận được gói này bằng cách gọi

Package p = Package.getPackage("com.example"); //(returns null) 

hoặc thậm chí có được một danh sách tất cả các gói bằng cách gọi

Packages[] ps = Package.getPackages(); 

Vấn đề là - nếu ClassLoader chưa nạp bất kỳ lớp học từ gói, nó sẽ không có sẵn cho các cuộc gọi chức năng này. Chúng ta có thể buộc nó để tải các gói bằng vũ lực có tốc độ tải một trong các lớp trong gói đầu tiên, như thế này:

this.getClass().getClassLoader().loadClass("com.example.SomeClass"); 
Package p = Package.getPackage("com.example"); //(returns non-null) 

Tuy nhiên, đây là hacky và đòi hỏi phải biết trước thời hạn tên của một số lớp thuộc về gói.

Vì vậy, câu hỏi đặt ra là - có cách nào để có được một thể hiện của gói theo tên, bất kể có hay không ClassLoader đã làm bất cứ điều gì? Có phải các giả định của tôi về cách tải lớp/gói dường như hoạt động trong tình huống này chính xác không?

+0

Cẩn thận với https://stackoverflow.com/questions/3455267/why-does-class-getpackage-return-the-same-package-for-classes-from-different-pac – Vadzim

Trả lời

11

Hoặc bạn có thể sử dụng thư mục gốc của lớp làm điểm bắt đầu và đi qua tất cả các tệp * .class và thư mục con. Điều này sẽ chỉ hoạt động nếu bạn biết tất cả các tệp .class của bạn sẽ nằm ở đâu trước.

Nguyên nhân của tất cả điều này là Java có tải lớp động, vì vậy các lớp có thể được tải tại thời gian chạy từ các vị trí không được biết tại thời gian biên dịch hoặc ngay cả khi khởi động. Do đó khái niệm về một gói chỉ là một vùng tên cho các lớp được nạp, không phải là một thư mục mà bạn có thể sử dụng để tìm kiếm chúng.

5

Tôi e rằng các giả định của bạn không hợp lệ. Các trình nạp lớp thực hiện lưu trữ sách theo gói khi chúng tải các lớp.

Bạn có thể chuyển một ký tự đại diện đến ClassLoader.getResources và buộc nó để nhận các lớp học trong một gói, do đó sẽ thực hiện công việc.

Bạn có thể tạo ClassLoader của riêng bạn gọi definePackage, nhưng điều đó sẽ không giúp bạn với các trình nạp lớp vani thông thường đang được sử dụng.

5

Tôi cho rằng bạn cần điều này vì bạn cần kiểm tra chú thích của nó. Nếu không, bạn sẽ không quan tâm đến việc có một tham chiếu Package mà chỉ các hoạt động là tất cả xung quanh việc truy cập các chú thích. Điều này dẫn đến giả định rằng bạn cũng có một package-info.java được định nghĩa ở đó với một số chú thích.

Nếu bạn kiểm tra java.lang.Package bạn sẽ thấy rằng getPackageInfo chỉ tải lớp gói-thông tin là lớp thông thường.

Tôi gặp vấn đề tương tự và đã đưa ra giải pháp này.

public static Package getPackage(String packageName) throws ClassNotFoundException { 
    Class.forName(packageName+".package-info"); // makes sure package info exist and that the class loader already knows about the package 
    return Package.getPackage(packageName); 
} 
Các vấn đề liên quan