2013-04-06 58 views
0

請考慮以下導入語句:爲什麼要定義多個導入?

import java.io. *; //有意義

import javax.servlet。*;

import javax.servlet.http。*;

是不是像我們已經包含「import javax.servlet。;」因此它會自動包含另一個導入語句,即「import javax.servlet.http。;」?

爲什麼「import javax.servlet.http。*」爲http明確定義?

請澄清,讓我知道如果我錯了。

回答

1

是的,你需要爲每個包做一個通配符導入。

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

「爲包裝層次命名結構是爲了便於以傳統方式舉辦相關的軟件包,但本身不是對具有相同的子包一包,禁止其他沒有意義簡單的名稱作爲頂級類型(第7.6節)在包聲明。

例如,有一個名爲oliver包和命名oliver.twist,或命名爲evelyn.woodevelyn.waugh包之間的另一個包之間沒有特殊的調用關係。也就是說,a中的代碼名爲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 

這是一個衆所周知的事實,程序員是懶惰(OK很多都是),所以有些程序員可能會這樣寫:

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

他/她現在有兩個外部API類和內部類在這一類的命名空間,這將是很容易意外上創建內部的依賴。

(你說之前「使內部類的包私人」 ...這是行不通的。有跡象表明,需要在com.example.weazellib.impl能夠利用班班com.example.weazellib。如果是後者是包私有的,那麼前者將無法使用它們。)

相比之下,在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是不明確的...... ,因爲超級通配符導入從一個以前不存在的包中取得類名的影響。

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

+0

那麼它真的很有意義,爲什麼你要導入整個「子包」的樹,如果你不會使用它們。 – 2013-04-07 00:24:30

+0

@kellax - 我無法弄清楚*你說什麼「有道理」。當前的模型,或帶有「超級通配符」導入的模型。我的觀點是,懶惰的程序員會使用超級通配符而不會思考......'因爲它不那麼簡單。 (就像在Java沒有檢查異常的情況下他們會忽略異常處理一樣)。而且,面對圖書館INTERNAL細節變化的穩定性也存在問題。 – 2013-04-07 00:32:24

+0

感謝您的回覆傢伙,但是有沒有官方的java文檔明確表示,子包的存在就像@ kellax提到的一樣? – Adarsh 2013-04-07 00:36:05

1

否當您導入某個導入的內容時,只導入特定的類或導入包以及屬於該包的所有類,但不包含屬於該包的子包的類。

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

例子:
比方說,你正在爲你的GUI應用程序視圖類,你可能要分開的擔憂,所以你會在你的瀏覽JComponents和你Listeners在你的控制器。

因此,在你查看你會導入:import javax.swing.*;這樣你會得到所有的JComponent類,但因爲你不需要event包您查看它是有道理的,只導入導入你的實際需要。即使是swingevent包有點相關,也不需要導入事件。

所以,當你在Java中導入的東西,你要麼導入整個包import javax.swing.*;隨着社會各界關心的軟件包,或者導入一個類的包中的類import javax.swing.JButton;

你永遠不會與它的所有導入包子程序包及其子程序包等。因爲它很可能不需要所有的程序包。

0

它在規範中定義了導入如何工作。

Java Language Spec

的原因是和javax.servlet.http是不同的包,並導入*僅在包中的成員帶來的。

此外,它不是一個好的主意,通配符導入,因爲它使代碼不易讀。

相關問題