Tôi nghĩ câu hỏi mà bạn có thể đang cố gắng đặt ra là, "Các gói trong Java là gì và từ khóa import
liên quan đến chúng như thế nào?". Sự nhầm lẫn của bạn về cấu trúc thư mục có thể xuất phát từ thực tế là một số ngôn ngữ khác có chỉ thị include
sử dụng tên tệp để bao gồm nội dung của tệp được chỉ định trong mã nguồn của bạn lúc biên dịch. C/C++ là ví dụ về các ngôn ngữ sử dụng loại chỉ thị include
này. Từ khóa import
của Java không hoạt động theo cách này. Như những người khác đã nói, từ khóa import
chỉ đơn giản là một cách viết tắt để tham khảo một hoặc nhiều lớp học trong một gói. Công việc thực sự được thực hiện bởi trình nạp lớp của Máy ảo Java (chi tiết bên dưới).
Hãy bắt đầu với định nghĩa của một "gói Java", như mô tả trong Wikipedia article:
gói Một Java là một cơ chế cho tổ chức các lớp Java vào không gian tên tương tự như các module của Modula. Các gói Java có thể được lưu trữ trong các tệp nén được gọi là tệp JAR, cho phép các lớp tải xuống nhanh hơn dưới dạng một nhóm thay vì một nhóm tại một thời điểm. Các lập trình viên cũng thường sử dụng các gói để tổ chức các lớp học thuộc số vào cùng một danh mục hoặc cung cấp chức năng tương tự.
Trong Java, mã nguồn file cho các lớp là trên thực tế bởi các thư mục có tổ chức, nhưng phương pháp mà theo đó các Java Virtual Machine (JVM) nằm các lớp khác với các ngôn ngữ như C/C++.
Giả sử trong mã nguồn của bạn, bạn có một gói có tên "com.foo.bar" và trong gói đó bạn có một lớp có tên là "MyClass". Tại thời gian biên dịch, vị trí của mã nguồn của lớp đó trong hệ thống tệp phải là {source}/com/foo/bar/MyClass.java
, trong đó {source}
là gốc của cây nguồn mà bạn đang biên soạn.
Một sự khác biệt giữa Java và các ngôn ngữ như C/C++ là khái niệm về trình nạp lớp. Trên thực tế, khái niệm về trình nạp lớp là một phần quan trọng trong kiến trúc của Máy ảo Java. Công việc của trình nạp lớp là định vị và tải bất kỳ tệp nào class
mà chương trình của bạn cần. Trình tải lớp Java "nguyên thủy" hoặc "mặc định" thường được JVM cung cấp. Nó là một lớp thông thường của loại ClassLoader
, và chứa một phương thức gọi là loadClass()
với định nghĩa sau đây:
// Loads the class with the specified name.
// Example: loadClass("org.apache.nutch.plugin.Extension")
Class loadClass(String name)
phương pháp loadClass()
này sẽ cố gắng xác định vị trí các tập tin class
cho lớp với tên cho trước, và nó tạo ra một đối tượng Class
có phương thức newInstance()
có khả năng khởi tạo lớp.
Trình tải lớp tìm kiếm tệp class
ở đâu? Trong đường dẫn lớp của JVM. Đường dẫn lớp đơn giản là danh sách các vị trí có thể tìm thấy các tệp class
. Các vị trí này có thể là các thư mục chứa các tệp class
. Nó thậm chí có thể chứa các tệp jar
, mà thậm chí có thể chứa nhiều tệp hơn class
. Trình nạp lớp mặc định có khả năng tìm kiếm bên trong các tệp jar
này để tìm kiếm các tệp class
. Như một lưu ý phụ, bạn có thể triển khai trình nạp lớp của riêng mình, ví dụ, cho phép các vị trí mạng (hoặc bất kỳ vị trí nào khác) được tìm kiếm cho các tệp class
.
Vì vậy, bây giờ chúng ta biết rằng có hay không "com.foo.bar.MyClass" là trong một tập tin class
trong cây nguồn của riêng bạn hoặc một tập tin class
bên trong một tập tin jar
đâu đó trong đường dẫn lớp của bạn, bộ nạp lớp sẽ tìm nó cho bạn, nếu nó tồn tại. Nếu nó không tồn tại, bạn sẽ nhận được ClassNotFoundException
.
Và bây giờ để giải quyết các import
keyword: tôi sẽ tham khảo ví dụ sau:
import com.foo.bar.MyClass;
...
public void someFunction() {
MyClass obj1 = new MyClass();
org.blah.MyClass obj2 = new org.blah.MyClass("some string argument");
}
Dòng đầu tiên chỉ đơn giản là một cách để nói với trình biên dịch "Bất cứ khi nào bạn nhìn thấy một biến khai báo đơn giản là loại MyClass
Giả sử tôi có nghĩa là com.foo.bar.MyClass
.Đó là những gì đang xảy ra trong trường hợp của obj1
.Trong trường hợp của obj2
, bạn đang nói với trình biên dịch "Tôi không muốn lớp com.foo.bar.MyClass
, tôi thực sự muốn org.blah.MyClass
". Vì vậy, các từ khóa import
chỉ là một simp Cách cắt giảm số lượng lập trình đánh máy phải làm để sử dụng các lớp khác. Tất cả các công cụ thú vị được thực hiện trong trình nạp lớp của JVM.
Để biết thêm thông tin về chính xác trình nạp lớp làm gì, tôi khuyên bạn nên đọc một bài viết có tên là The Basics of Java Class Loaders
Câu hỏi không rõ ràng. – pjp