2009-06-27 19 views
16

Ví dụNhập bằng Java như thế nào?

import org.apache.nutch.plugin.Extension, 

mặc dù sử dụng nhiều lần,

Tôi không biết nhiều những gì được thực hiện chủ yếu.

EDIT: Có phải là org.apache.nutch.plugin về cơ bản 4 thư mục hoặc ít hơn 4 thư mục có tên org.apache?

+0

Câu hỏi không rõ ràng. – pjp

Trả lời

13

Tất cả những gì bạn đang làm là giúp bạn nhập. Thay vì phải nhập "org.apache.nutch.plugin.Extension" mỗi lần bạn muốn sử dụng, nhập sẽ cho phép bạn tham chiếu đến nó bằng tên ngắn, "Tiện ích mở rộng".

Đừng nhầm lẫn với từ "nhập" - nó không tải tệp .class hoặc bất kỳ thứ gì tương tự. Trình nạp lớp sẽ tìm kiếm nó trên CLASSPATH và tải nó vào không gian perm trong lần đầu tiên mã của bạn yêu cầu nó.

CẬP NHẬT: Là nhà phát triển, bạn phải biết rằng các gói được liên kết với các thư mục. Nếu bạn tạo một gói "com.foo.bar.baz" trong tệp .java của bạn, nó sẽ phải được lưu trữ trong thư mục com/foo/bar/baz.

Nhưng khi bạn tải xuống tệp JAR, như thư viện Apache Nutch đó, không có thư mục nào liên quan đến quan điểm của bạn. Người đã tạo JAR phải nén cấu trúc thư mục thích hợp, mà bạn có thể xem như là đường dẫn đến tệp .class nếu bạn mở JAR bằng WinZip. Bạn chỉ cần đặt JAR đó trong CLASSPATH cho ứng dụng của bạn khi bạn biên dịch và chạy.

+0

Ý của tôi là "org.apache.nutch.plugin" về cơ bản là 4 thư mục? – omg

+0

+1 Mọi người thường quên "nhập" chỉ là viết tắt. –

+0

@Shore - Các nhà thiết kế của Java đã xác định các gói với cấu trúc thư mục như một quy ước. Một cách khác để nghĩ về chúng đơn giản là không gian tên. Cả bạn và tôi đều có thể phát triển các lớp có tên là "Foo", miễn là chúng ta có thể phân biệt chúng với các gói/không gian tên. "Tôi không chắc chắn, nhưng tôi tin rằng đó là cách C++ và C# sử dụng chúng. – duffymo

2

Nhập chỉ là gợi ý cho trình biên dịch cho biết cách tìm ra tên đầy đủ của các lớp.

Vì vậy, nếu bạn có "nhập java.util. *;" và trong mã của bạn, bạn đang làm một cái gì đó như "new ArrayList()", khi trình biên dịch xử lý biểu thức này trước tiên nó cần tìm tên đầy đủ của loại ArrayList. Nó làm như vậy bằng cách đi qua danh sách nhập khẩu và thêm ArrayList vào mỗi lần nhập. Cụ thể, khi nó thêm ArrayList vào java.util, nó nhận được java.util.ArrayList của FQN. Sau đó nó tìm kiếm FQN này trong đường dẫn lớp của nó. Nếu nó tìm thấy một lớp với tên như vậy thì nó biết rằng java.util.ArrayList là tên đúng.

+0

Tôi biết về điều đó, mặc dù: ( – omg

0

Về cơ bản khi bạn tạo một lớp, bạn có thể khai báo lớp học đó là một phần của gói. Cá nhân tôi không có nhiều kinh nghiệm khi làm các gói. Tuy nhiên, afaik, về cơ bản có nghĩa là bạn đang nhập lớp Extension từ gói org.apache.nutch.plugin.

+0

Vì vậy, những gì là mối quan hệ tween gói và thư mục? – omg

+0

http://en.wikipedia.org/wiki/ Java_packages – Thomas

0

Bù tắt Thomas' câu trả lời, org.apache.nutch.plugin là đường dẫn đến (các) tệp lớp bạn muốn nhập. Tôi không chắc chắn về gói này, nhưng nói chung bạn sẽ có một tệp .jar mà bạn thêm vào classpath của bạn, và câu lệnh import của bạn trỏ tới thư mục "./[classpath]/[jarfile]/org/apache/ nutch/plugin "

+0

Có thể như sau: ./[classpath]/[jarfile]/org.apache/nutch/plugin ? – omg

1

là" org.apache.nutch.plugin "về cơ bản là 4 thư mục?

Nếu bạn có một lớp có tên là org.apache.nutch.plugin.Extension, sau đó nó được lưu trữ ở đâu đó trong classpath như một tập tin org/apache/nutch/plugin/Extension.class. Vì vậy, thư mục gốc chứa bốn thư mục con lồng nhau ("org", "apache", "nutch", "plugin") mà lần lượt chứa tệp lớp.

+0

Có thể org.apache là một thư mục thay vì hai? – omg

+0

Không. Mỗi từ trong tên gói là thư mục riêng của nó. –

1

import org.apache.nutch.plugin.Extension là phím tắt thời gian biên dịch cho phép bạn tham khảo lớp Tiện ích mở rộng mà không sử dụng tên đầy đủ của lớp học.Nó không có ý nghĩa trong thời gian chạy, nó chỉ là một thủ thuật thời gian biên dịch để lưu gõ.

Theo quy ước, tệp .class cho lớp này sẽ nằm trong thư mục org/apache/nutch/plugin trong hệ thống tệp hoặc tệp jar, một trong hai tệp cần phải có trong classpath của bạn, cả hai lúc biên dịch và thời gian chạy. Nếu tệp .class nằm trong tệp jar thì tệp jar đó phải nằm trong đường dẫn lớp của bạn. Nếu tệp .class nằm trong một thư mục, thì thư mục là thư mục cha của thư mục "org" cần phải nằm trong đường dẫn lớp của bạn. Ví dụ, nếu lớp được đặt trong thư mục c: \ myproject \ bin \ org \ apache \ nutch \ plugin thì thư mục c: \ myproject \ bin sẽ cần phải là một phần của classpath.

Nếu bạn quan tâm đến việc tìm ra nơi lớp được tải từ khi bạn chạy chương trình của mình, hãy sử dụng tùy chọn dòng lệnh java -verbose:class. Nó sẽ cho bạn biết thư mục hoặc tệp jar nào JVM đã tìm thấy lớp đó.

+0

Cảm ơn bạn đã trả lời, nhưng bây giờ tập trung của tôi là: Có thể org.apache là một thư mục thay vì hai? dường như không ai có câu trả lời rõ ràng? – omg

+0

bạn không thể sử dụng thư mục gói hoặc tên tệp. trong chúng. –

0

bạn không thể có thư mục có tên org.apache làm gói. trình biên dịch sẽ không hiểu tên đó và sẽ tìm cấu trúc thư mục org/apache khi bạn nhập bất kỳ lớp nào từ gói đó.

cũng, không nhầm lẫn câu lệnh Java import với hướng dẫn tiền xử lý C #include. tuyên bố import giống như họ đã nói, viết tắt để bạn nhập ít ký tự hơn khi đề cập đến tên lớp.

+0

Bất kỳ tham chiếu nào để chứng minh "không thể có thư mục có tên org.apache như một gói. Trình biên dịch sẽ không hiểu tên đó"? – omg

+0

Chẳng gì bằng thử tự mình chứng minh điều đó. Spoiler: CD1 là chính xác. –

+0

như William đã nói, tôi vừa thử nó ở đây, trình biên dịch không nhận ra câu lệnh nhập của tôi. – cd1

31

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 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ác vấn đề liên quan