2011-09-29 38 views
9

我有興趣使用Java 7 SDK中的某些NIO2功能(特別是file system watchers),但是我不想爲Java 7編譯我的類並排除Java 6次運行。主要是因爲我想保持與Mac OS X的兼容性,也是因爲我不想強制用戶升級。在Java中使用Java 7 SDK功能6

這可能嗎?什麼是最好的方式來做到這一點?任何鏈接或例子?

下面是我可以想到的一些方法:使用不同的編譯器編譯類文件並基於Java版本動態加載它?或者也許使用反射?或者也許只有Java 7的編譯器設置來生成Java 6兼容的類?

我正在尋找一種不會變成醜陋混亂的解決方案:),所以理想情況下我可以編寫兩個接口實現,一個使用新功能,另一個不使用,然後動態選擇一個,而不是在全國各地做反思性會議。

+0

由於我推測這些功能在SE7中開始存在,您如何認爲您可以使用SE6兼容模式進行編譯並保留它們? – KevinDTimm

+0

我想要做的只是在Java 7運行時執行程序時使用它們,如果不是,則會退回到其他行爲上。請注意,我正在談論Java 7 SDK功能,而不是語言功能。 –

+0

對不起,兩個代碼庫將是必要的(或者至少每個環境都有單獨的文件處理基礎,併爲每個版本創建單獨的輸出,因爲在版本X中編譯的代碼通常不會在任何較低編號的版本中工作) – KevinDTimm

回答

9

只需使用-target 1.6構建並組織代碼,以便可以在使用1.7的模塊周圍清楚地捕獲ClassNotFoundExceptions和NoClassDefFoundErrors。例如,可能用一個單獨的類加載器加載它們。

+0

它的工作原理,謝謝!我在Eclipse中配置了JDK 7以處理語法突出顯示,並使用目標Java 6構建。對於不存在的方法調用,您必須捕獲NoSuchMethodError。 –

+0

@Laurens @EJP。我不明白,你怎麼能用-target 1.6來創建源代碼1.7?它不會給你:'javac:源版本1.7需要目標版本1.7' – Pacerier

+0

@Pacerier技巧是使用源代碼1.6而不是1.7來編譯,只需調用1.7 SDK中的方法即可。可能需要在編輯器中進行一些配置以防止抱怨,並使代碼完成工作,否則它就會起作用。 –

0

對於在Java 7中添加的某些元素,您可能會找到能夠提供該功能的Java 6 jsr jar。但是我不相信File System Watcher會出現這種情況。

+0

如果運行在Java 6上,我不需要這些功能,對於在Java 7上運行的用戶是可選的。在這種情況下,我可能回到輪詢或顯式刷新行爲。 –

+3

考慮JNotify –

0

就文件系統觀察者而言,在Java 7之前,我曾經每隔幾秒鐘輪詢一次文件的屬性以檢查它沒有改變。這不太好,但實際上它沒有使用明顯的資源,並且從最終用戶的角度來看似乎也是一樣的。

如果你正在經歷一個更全面的圖書館,請檢查http://commons.apache.org/jci/commons-jci-fam/index.html - 我相信這樣做有點類似,儘管我從來沒有用過它。

指定源代碼1.7和目標1.6我敢肯定不會工作,我嘗試了一段時間,因爲一個不同的原因,從內存中JVM抱怨不兼容的標誌(我的猜測是因爲7中新的invokedynamic )

1

你可以像工具箱指出的那樣輕鬆地爲java 1.6構建。但是,您需要確保不會意外訪問java 6中不存在的任何方法。這會在您的生產代碼中導致運行時異常。

如果您使用的是maven,您可以使用maven-enforcer插件,它確保沒有java 1.7類或方法調用潛入您爲1.6構建的代碼中。

一個例子是從java 1.4到1.5的變化。我正在用1.4的目標建設,而我不小心使用了:

new BigDecimal(5); 

這個編譯好了,對我來說運行良好。但是因爲客戶端仍在使用1.4,所以失敗了。因爲這個構造函數在1.4中不存在。它是在1.5版本中引入的。

另一種解決方案是構建幾個jar,一個使用新的nio,一個使用舊的東西,並在安裝時檢測用戶是否運行java 1.7。如果是這樣,請添加包含適當實現的jar。