簡體   English   中英

為什么要定義多個導入?

[英]Why to define multiple imports?

請考慮以下import語句:

import java.io. *; // 說得通

import javax.servlet。*;

import javax.servlet.http。*;

是不是我們已經包含“import javax.servlet 。;” 因此它會自動包含另一個import語句,也就是“import javax.servlet.http . ;”?

為什么為http顯式定義了“import javax.servlet.http。*”?

如果我錯了,請澄清並告訴我。

否,當您導入某些內容時,您只導入一個特定的類,或者導入該包,並導入該屬性的所有類,而不是屬於該包的子包的類。

每個包都包含一些相關的類和子包。 子包中的類不一定與父包中的類相關。 因此,導入這些也沒有意義。 這樣您可以避免不必要的導入並保持項目清潔。

例:
假設您正在為GUI應用程序構建一個View類,您可能希望將它們分開,這樣您就可以在View中使用JComponents ,在控制器中使用Listeners

因此,在您的視圖中,您將導入: import javax.swing.*; 這樣你就可以獲得所有的JComponent類,但是因為你不需要在View中使用event包,所以導入只導入你真正需要的東西。 即使是swingevent包也有些相關,也沒有必要導入事件。

因此,當您使用Java導入內容時,您要么導入整個包import javax.swing.*; 使用與包有關的所有類,或者導入包的一個類import javax.swing.JButton;

您永遠不會導入包含所有子包及其子包等的包。因為您很可能不需要所有這些包。

是的,您需要為每個包執行通配符導入。

為什么? 就JLS而言,“com.example”和“com.example.pkg”是不相關的包。 JLS中提到了子包的概念,但沒有相關的語義。 特別是不在“訪問”規則中。 JLS 7.1說:

“包的分層命名結構旨在方便以傳統方式組織相關包,但除了禁止包含具有與頂級類型相同的簡單名稱的子包之外,它本身沒有意義(第7.6節) )在該包中聲明。

例如,有一個名為包之間沒有特殊的訪問關系oliver和另一包命名oliver.twist ,或命名的包間evelyn.woodevelyn.waugh 也就是說,命名包中的代碼oliver.twist必須聲明的包中的類型沒有更好的訪問oliver比任何其他封裝代碼“。

(並且允許導入許多不相關的包的結構會產生不良后果......見下文。)

但為什么? 因為這是語言的設計方式。

但為什么? 您需要向Java語言設計團隊詢問他們在20世紀90年代早期做出設計決策時的想法。


但也許我們可以看到如果有多包通配符導入會發生什么。

考慮這個包結構,這是一個非常常見的模式:

  com.example.weazellib - contains the public API classes for the library
  com.example.weazellib.impl - contains implementation classes that 
                               shouldn't be used by external clients

眾所周知,程序員很懶(很好),所以一些程序員可能會這樣寫:

  import com.example.weazellib.**    // hypothetical syntax

他/她現在將擁有此類名稱空間中的外部API類和內部類,並且很容易意外地在內部創建依賴項。

(並且在你說“使內部類包私有”之前 ......這不起作用com.example.weazellib中的類需要能夠使用com.example.weazellib.impl類。如果后者包私有,然后前者將無法使用它們。)

相比之下,在Java沒有導入包“樹”的通配符的世界中,你不能意外地做到這一點。 你必須故意導入impl包。 這是一件好事 ,比為多個包編寫通配符導入的“不方便”要重要得多。


另一個問題是通配符導入不利於長期源代碼穩定性,超級通配符會使情況變得更糟。

假設程序員決定在他的代碼中導入com.example.weazellibcom.example.weazellib.impl是正確的事情......並使用超級通配符導入兩者。 並且假設他編寫了他的代碼以使用com.example.weazellib.impl.ToesImpl ...作為ToesImpl

現在考慮如果“weazellib”開發人員添加第三個包com.example.weazellib.impl2包含替代實現類的情況會發生什么...與impl的類具有相同的簡單名稱; 例如我們現在有這樣的課程:

com.example.weazellib.impl.ToesImpl
com.example.weazellib.impl2.ToesImpl

怎么了? 那么現在程序員代碼中有一個編譯錯誤。 ToesImpl是不明確的...... 因為超級通配符導入從一個以前沒有的包中提取類名的效果

請注意,常規通配符導入存在同樣的問題。 這就是很多人不使用通配符導入的原因。 但毫無疑問,超級通配符會讓問題變得更糟。

它在規范中定義了導入的工作原理。

請參閱Java語言規范

原因是javax.servlet和javax.servlet.http是不同的包,而import *只引入包成員。

此外,它不是一個好主意導入外卡,因為它使代碼可讀性降低。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM