2012-11-25 47 views
1

這是一個基本的問題。Java字節碼優化

我不應該在元數據豆類運行代碼。所有的元數據bean位於元數據包下。

現在,

我使用反射API來找出一個類是否位於元數據包。

if (newEntity.getClass().getPackage().getName().contains("metadata")) 

我用這個if在這個代碼裏的幾個地方。

的問題是:

boolean isMetadata = false 
if (newEntity.getClass().getPackage().getName().contains("metadata")) { 
    isMetadata = true; 
} 

C++做優化和知道這個代碼已經被調用,它不會再調用它:我應該有這樣做一次。 JAVA是否會優化?我知道反射API是一個重拍,我寧願 不要失去昂貴的運行時間。

+1

正確的做法是:(1)選擇您認爲會導致最清晰,最不容易出錯的代碼的任何選項; (2)使用分析器來查找實際的性能瓶頸; (3)優化那些。 – NPE

+2

將程序包名稱用作程序中的標誌聽起來不像是非常好的設計。我不確定你在做什麼,但有一個可能更好/更簡單的方法來實現它 – Guillaume

回答

6

你當然應該檢查是否真的有把任何工作納入優化前的性能問題。 getClass()可能已經很快了(反正比instanceof快)。您可能可能緩存元數據包中的一組類,因此您無需繼續檢查包名。

如果您確實需要比較軟件包,則可以使用Package.getPackage(String name)方法找到元數據包一次,然後像以前一樣調用getClass().getPackage(),然後比較兩個軟件包對象。

這比檢查包名稱中的字符串更快更優雅,但如果存在多個類加載器,則可能無法正常工作,因爲Package對象不等於(==),而Package未覆蓋-ride .equals()。考慮一下,它可能不能保證在單個類加載器上工作,但我懷疑在實踐中,你會得到相同的Package實例而不是另一個副本 - 這將是明智的首先檢查!例如:

String.class.getPackage() == Integer.class.getPackage() // should be true 

更新如果選中source codeClass.getPackage()Package.getPackage()ClassLoader.getPackage()你可以看到他們緩存Package對象,所以你應該是安全的使用單一類加載器包命名約定的

一個問題時,對它們進行比較是你必須在整個過程中執行和維護它代碼庫,這可能會隨着時間的推移而成爲維護問題。識別類的更明確的方式可能會更好。

識別類特殊羣體的替代方法包括:

  • 讓您的元數據bean實現一個標記接口
  • 使用Java註解來標記元數據豆類
  • 製作所有 bean實現一個共同的接口用一個可以調用的方法來檢查是否在你定義的特定類別中。這很醜陋,因爲它基本上是複製類型系統,但會很快,因爲它不需要反射。