2012-09-29 11 views
9

Trong một Dự án Java , giữ tất cả các tệp .java trong cùng một thư mục có nghĩa là chúng nằm trong cùng một gói không?Sự khác biệt giữa Gói và Thư mục trong Java

Sự khác nhau trong số tạo gói cho dự án của chúng tôi so với việc giữ tất cả các tệp dự án trong một thư mục là gì?

This thread không thực sự giải quyết được câu hỏi của tôi.

+4

googling tiêu đề của bạn cung cấp liên kết này http://stackoverflow.com/questions/9510932/java-package-vs-folder-structure-what-is-the-difference – gigadot

+0

tôi không hiểu.hãy làm rõ.! – jbmeta

+2

Điều này có nghĩa là câu hỏi đã được hỏi và bạn nên tra cứu câu hỏi này và các câu hỏi tương tự trước. –

Trả lời

12

Có mối quan hệ giữa gói và thư mục, nhưng đó là mối quan hệ mà bạn phải duy trì. Nếu bạn có một lớp trong "mypackage1.mypackage2", điều đó có nghĩa là lệnh java sẽ mong đợi tìm thấy nó trong cấu trúc thư mục có tên "mypackage1 \ mypackage2" (giả sử "ký hiệu Windows" ngược), với cấu trúc thư mục đó nhúng trong một thư mục (chúng ta hãy gọi nó là "myjava") có tên là trong classpath (hoặc người nào khác là trực tiếp trong "thư mục hiện tại").

Vì vậy, lớp Java của bạn (trong đó nội bộ nói package mypackage1.mypackage2;) là trong, nói, "\ Users \ myName \ myjava \ mypackage1 \ mypackage2 \", và bạn đặt "\ Users \ myName \ myjava" trong đường dẫn lớp hoặc bạn có thư mục hiện tại của bạn được đặt thành "\ Users \ myName \ myjava".

Nếu bạn kết hợp điều này, cả lớp sẽ không được tìm thấy chút nào, hoặc bạn sẽ gặp lỗi giống như "NoClassDefFoundError" vô tận.

Khi đến lý do tại sao người ta sẽ sử dụng gói (và thư mục), lý do phải làm với "không gian tên" và "tách mối quan tâm" (xem những điều đó). Java sẽ khó khăn hơn nhiều để giữ thẳng nếu không có gói nào và tất cả các "java.lang", "java.io", "sun.misc", các lớp et al cùng nhau. Trước hết, người ta sẽ phải sử dụng tên "tiền tố" để giữ chúng thẳng và tránh xung đột tên. Và nhiều nhóm hợp lý sẽ bị mất.

Với các dự án của riêng bạn, bạn không cần sử dụng gói cho các chương trình đơn giản mà bạn viết cho chính mình, nhưng nếu bạn viết một cái gì đó bạn có thể tặng cho người khác, hãy lịch sự sử dụng gói như "myname.myproject" (thay thế tên và dự án của bạn tất nhiên), vì vậy người bạn đưa nó vào có thể kết hợp nó với những người khác mà không có xung đột tên.

Trong các ứng dụng lớn, bạn sẽ tìm thấy bằng cách sử dụng các mức phân tách cao hơn giúp bạn giữ các chức năng thẳng, vì vậy bạn biết mọi thứ ở đâu. Nó cũng ngăn cản bạn từ "vượt qua ranh giới" giữa các khu chức năng khác nhau, vì vậy bạn không nhận được logic không liên quan entertwined.

Eclipse (nếu bạn sử dụng) loại lộn xộn vấn đề một chút vì nó "muốn" cung cấp tên thư mục và tên gói và đôi khi (nhưng không phải lúc nào) giữ chúng được đồng bộ.

+0

Vì vậy, cho phép nói rằng tôi có một tập tin .java trong thư mục \ java \ limbo \ mà đòi hỏi phải sử dụng một lớp (tập tin another.java) từ tập tin khác mà cũng trong cùng một \ java \ limbo \ place, vào đầu cả hai tập tin tôi có _package limbo; _ bằng văn bản nhưng khi tôi biên dịch tôi nhận được một lỗi ClassNotFound cho các tập tin nắm tay mà đòi hỏi các lớp thứ hai trong cùng một thư mục, làm thế nào? – jbmeta

+0

@jtnks - Khi biên soạn bạn phải được thiết lập với một đường dẫn lớp hợp lệ, giống như khi chạy lệnh 'java'. Đối với kịch bản của bạn, 'cd \ java' và sau đó chạy' javac limbo \ MyClass.java'. Điều này đặt cả hai lớp vào vị trí thích hợp của chúng liên quan đến tên gói và cấu trúc thư mục của chúng. –

+0

Cảm ơn rất nhiều @HotLicks .. nó hoạt động tốt và bây giờ tất cả đóng gói của nó độc đáo quá. !! – jbmeta

6
  • Gói cung cấp logic namespace đến các lớp học của bạn ..

  • Và những gói được lưu trữ dưới dạng các cấp thư mục (họ đang chuyển đổi sang lồng thư mục) để cung cấp vật lý nhóm (không gian tên) cho các lớp học của bạn ..

Ngoài ra, lưu ý rằng không gian tên physical phải phù hợp với không gian tên logical .. Bạn không có thể có lớp học của bạn với package com.demo, dưới cấu trúc thư mục: - \com\demo\temp\, nó phải được dưới \com\demo\, và thư mục này sẽ được thêm vào classpath để lớp học của bạn là có thể nhìn thấy để JVM khi nó chạy mã của bạn ..

Giả sử bạn ha ve theo cấu trúc thư mục: -

A
|
+ - Sample.java (chứa Demo lớp dưới gói B)
|
+ - Outer.java (chứa Demo lớp - không có gói)
|
+ - B
|       |
|     + - Demo.class
|
+ - C
|       |
|     + - Abc.class
|
+ - Demo.class

Giả sử, lớp học của bạn Abc.classDemo.class (dưới thư mục A), không được xác định dưới bất kỳ gói, trong khi lớp học của bạn Demo.class (dưới thư mục B) được định nghĩa dưới package B . Vì vậy, bạn cần phải có hai thư mục trong classpath của bạn: - \A (đối với hai lớp: - Demo.classB.Demo.class) và \A\C (đối với lớp Abc.class) ..

  • Lớp học dưới gói khác nhau có thể sử dụng cùng một tên. Đó là lý do tại sao sẽ không có bất kỳ xung đột nào giữa hai số Demo.class được xác định ở trên .. Bởi vì chúng nằm trong các khác nhau packages. Đó là toàn bộ điểm chia chúng thành namespaces .. Điều này có lợi, bởi vì bạn sẽ không hết tên duy nhất cho các lớp học của bạn.
4

Hiểu hệ thống phụ bộ nạp lớp sẽ trả lời truy vấn của bạn.

Với tham chiếu đến Inside JVM by Bill Venners

Cho một loại tên đầy đủ, lớp nạp nguyên thủy phải trong một số nỗ lực cách để xác định vị trí một file với tên đơn giản của loại cộng ".class". Do đó, JVM tìm kiếm đường dẫn thư mục do người dùng định nghĩa được lưu trữ trong một biến môi trường có tên là CLASSPATH. Bộ tải nguyên thủy trông trong mỗi thư mục, theo thứ tự các thư mục xuất hiện trong CLASSPATH, cho đến khi tìm thấy tệp có tên thích hợp: loại tên đơn giản cộng với ".class".Trừ khi loại là một phần của gói chưa được đặt tên, trình tải nguyên thủy dự kiến ​​tệp sẽ nằm trong một thư mục con của một thư mục trong CLASSPATH. Tên đường dẫn của thư mục phụ được tạo từ tên gói của loại. Ví dụ , nếu trình nạp lớp nguyên thủy đang tìm kiếm lớp java.lang.Object, nó sẽ tìm Object.class trong thư mục con java \ lang của mỗi thư mục CLASSPATH.

+0

Bỏ phiếu để tham khảo các thông số kỹ thuật thực tế. – Chad