2011-07-29 269 views
10

是否有可能在java中導入和使用兩個具有相同名稱和包的不同類?可能使用兩個具有相同名稱和相同包的java類?

例如,假設我有兩個名爲「com.foo.Bar」的類稍有不同。我希望能夠同時使用,但我有一個限制(由於愚蠢的反射垃圾),迫使我保持​​名稱和包裝相同。

java是否有一些功能可以導入和隔離這些類中的每一個?

詳細說明,我改變了我的avro模式,他們不應該被改變(哎呀!),現在我想回去改變舊的avro文件,這些文件不能被我的新的模式轉換成可以被我的新模式讀取的文件。 Avro似乎強迫你使用特定的類和包名稱加載文件。

+0

如果頂級類型的名稱顯示爲在同一個包中聲明的任何其他頂級類或接口類型的名稱,則會出現編譯時錯誤。 – roshan

回答

5

不,java包正好用來避免這個問題。

+1

我不認爲包裝類的想法將工作。讓2個同名的類爲C1和C2;和它們各自的包裝紙W1和W2。類加載器將(1)加載W1,這會導致它加載(2)加載C1。然後類加載器將(3)加載W2。它會認爲它已經加載了C2(因爲名字相同),並且你的W2類會包裝C1。 – emory

0

在Java中沒有名稱空間,只有在C#中,所以我假設你是指包。每個項目只能有一個完全合格的名稱。

0

從技術上講,可以使用一些低級別的技巧來完成,比如重寫字節級代碼。據我知道不同的Java crypter /加密器的工作就像是 - 他們有很多的類調用的A.class B.class C.class等

+0

它不一定是低級或欺騙。單獨的類加載器實例是要走的路。 – Mishax

0

如果你真的最肯定必須這樣做這可以通過使用不同的類加載器和可能的反射來實現。

這不是Java的工作原理,也不是故意允許的 - 你不應該做一些愚蠢的事情,這些事情會給你帶來麻煩。

6

是的。您需要實現自己的Classloader並玩一些遊戲,以便在運行時訪問這兩者。

我敢肯定,這是可能的,因爲我遇到了一個非常難以調試的問題,其中有人在他們的產品中有一個奇怪的類加載器,它搞亂了加載庫並提供來自2個不同版本的同一文件的2個不同版本的圖書館。

但是,這聽起來像一個INCREDIBLY壞主意。我會回去找一種解決問題的方法。從長遠來看,這隻會讓你心痛。哎呀,它可能已經是,當你調查類裝載機。

編輯:具體來說,你不能「導入」兩者。但是你可以在運行時訪問它們。

+0

我想你只需要儘可能多的單獨的類加載器實例(其中一個可以是引導類加載器),因爲你想引用同名類。您實際上不需要爲此編寫自己的類加載器。 – Mishax

0

這聽起來像你需要在一個名爲com.foo.Bar的接口中定義你的方法簽名。然後提供兩個不同的接口具體實現(比如com.foo.DefaultBar和com.foo.SpecialBar)。這樣,您可以根據接口類型進行編程,並根據需要在兩種不同的實現之間切換。

你能詳細說明你的意思是「反射性廢話」嗎?這可以提供洞察你的確切問題。

不要亂用類加載器或任何其他低級別的詭計。解決這些問題的最佳方法是首先要有明確的設計,任何人都能理解。

+1

我們以我們應該有的方式更改了我們的avro模式,所以我正在嘗試編寫hadoop作業來修復使用舊模式的文件。 Avro似乎強迫你使用相同的類和包名稱。 – guidoism

0

如前所述編寫自己的類加載器或另外使用像春分一個OSGi框架這確實類加載你

1

是的。它確實需要你自己製作類加載器,儘管

我已經在github上製作了demo

相關問題