[英]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
包,所以導入只導入你真正需要的東西。 即使是swing
和event
包也有些相關,也沒有必要導入事件。
因此,當您使用Java導入內容時,您要么導入整個包import javax.swing.*;
使用與包有關的所有類,或者導入包的一個類import javax.swing.JButton;
您永遠不會導入包含所有子包及其子包等的包。因為您很可能不需要所有這些包。
是的,您需要為每個包執行通配符導入。
為什么? 就JLS而言,“com.example”和“com.example.pkg”是不相關的包。 JLS中提到了子包的概念,但沒有相關的語義。 特別是不在“訪問”規則中。 JLS 7.1說:
“包的分層命名結構旨在方便以傳統方式組織相關包,但除了禁止包含具有與頂級類型相同的簡單名稱的子包之外,它本身沒有意義(第7.6節) )在該包中聲明。
例如,有一個名為包之間沒有特殊的訪問關系
oliver
和另一包命名oliver.twist
,或命名的包間evelyn.wood
和evelyn.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.weazellib
和com.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.