2011-01-21 79 views
8

真的不可能在jar文件中隱藏一些類嗎?在jar文件中隱藏類

我不想讓類的直接實例化,以保持它更靈活。這個罐子裏只能看到工廠(或者一個門面)。

除了創建兩個項目之外,還有別的辦法解決這個問題嗎? (兩個項目:第一個包含的類(實現)和第一個另外一個引用,幷包含了工廠;後來只有第二個將被引用)

+1

我不確定你的意思是「隱藏」。 Jar文件只是.zip文件,所以任何人都可以打開它們並在裏面看到你的類文件。 – jonescb 2011-01-21 14:07:14

+0

我只是想避免這些類可以在外部(偶然)用於實例化。 – nrainer 2011-01-21 14:16:36

+1

我確實認爲你應該相信你的課程的用戶,並提供足夠的文檔來說明使用什麼以及不應該使用什麼。無論如何,你無法防止所有使用你的罐子的開發人員犯的錯誤。當然,一種選擇是讓自己的構造函數變得如此複雜,沒有人能夠理解它們,並且會自然地回退到工廠類中:D – 2011-01-21 14:25:43

回答

3

我認爲如果你的公共工廠方法試圖返回一些「隱藏」的東西,你會遇到編譯器故障或警告。

不,你不能隱藏一個公共課程,而無需重新實現你自己的ClassLoader或使用OSGi或類似的東西。

你可以做的是將接口API與實現分開,有一個只包含接口的項目和另一個包含實現的項目。但是,您仍然無法隱藏實現類。

2

Obfuscation可以幫助你莫名其妙

+0

借調,即使它沒有隱藏它。 – 2011-01-21 14:10:40

2

對於標準的類加載器來說,這是不可能的。 OSGi認爲這個概念使其他包只能看到一些包,而不是其他包(即公共API和內部實現的分離)。

如果你是usinf日食可能會強制執行這些規則與this

5

我理解你不知道的隱藏實際的課程,只是防止其工廠類以外的工程。我認爲這可以通過在類構造函數中使用包私有(默認)可見性很容易實現。唯一的限制是你需要將類和工廠放在同一個包中,所以在中等到更大的代碼庫中可能會產生不必要的複雜。

3

如果我正確理解你的問題,你想確保你的庫的用戶被迫使用你的工廠來實例化它們的對象,而不是使用構造函數本身。

正如我所看到的,有兩種可能性,其中之一是愚蠢的,但在少數特定情況下可用,另一種可能是最實用且最常用的方式。

  1. 你可以讓所有的類到 工廠 private inner classes。如果您每個班級有一個工廠 ,但是如果您有很多 不同的班級通過一個工廠管理 ,則幾乎不可能 可行。
  2. 您可以使用protected訪問修飾符 限制訪問您的類 構造函數。 這是常見的 練習時使用factory pattern
1

如果我在正確理解你說「不允許直接實例化類來保持它更靈活」時,正確執行的外觀模式將處理此問題。

限制你想隱藏到包範圍的所有類的構造函數。打開外觀類到公共範圍。

http://mindprod.com/jgloss/packagescope.html

「如果你在 類變量或方法,你不希望客戶端類直接訪問的 , 不給它一個公開,保護或 私人由於 在Java設計中的疏忽,您的 無法明確聲明默認的 「包」的可訪問性。該包的其他成員 將能夠看到它, 但包外的類 繼承你的,不會的。 受保護的可訪問性屬性 提供了稍微更多的可見性。 A 受保護的方法對 繼承類是可見的,即使不是 的一部分也是相同的包。包的範圍 (默認)方法不是。那就是 保護套和 套件範圍之間的唯一區別。 「

0

你可以做這樣的魔法使用自定義類加載器,但是:

  • 正確的分離只會在你的類加載器配備一個項目可用;
  • 這真的值得懷疑的努力創建這樣的加載器是值得的

在這種情況下,我會做類似於我們在標準Java中看到的東西。Egyou請參閱javax.xml.stream.XMLInputFactory但在某處您有com.sun.xml.internal.stream.XMLInputFactoryImpl。這是完全編譯的,如果你寫:

new com.sun.xml.internal.stream.XMLInputFactoryImpl() 

雖然你將很難做到這一點:-)有了一個系統屬性,你可以控制被加載的實際執行情況。對我來說,在許多情況下這種方法都很好。

我希望我能正確理解你的問題;)

乾杯!

1

對於您的問題有兩種解決方案,不涉及將所有類保留在同一個包中。

第一種是使用(Practical API Design,Tulach 2008)中描述的Friend Accessor/Friend Package模式。

第二個是使用OSGi。有一篇文章here解釋了OSGi如何完成這個。

相關問題:12,34