java向后兼容吗_Java向后不兼容历史的观察
java向后兼容嗎
在大多數(shù)情況下,Java是一個(gè)非常向后兼容的編程語(yǔ)言。 這樣做的好處是,與大規(guī)模破壞兼容性相比,大型系統(tǒng)通常可以相對(duì)輕松的方式升級(jí)為使用Java的較新版本。 這樣做的主要缺點(diǎn)是Java堅(jiān)持了一些設(shè)計(jì)決策,這些決策自那時(shí)以來(lái)就被認(rèn)為比理想情況要差,但必須留在原處以保持一般的向后兼容性。 即使Java與向后兼容性有相當(dāng)強(qiáng)的聯(lián)系,但Java的每個(gè)主要版本中仍存在差異,這些差異可能會(huì)在升級(jí)時(shí)破壞基于Java的應(yīng)用程序。 這些可能發(fā)生的中斷(最常見(jiàn)于“拐角事件”中)是本文的主題。
Sun Microsystems和Oracle提供了與Java升級(jí)相關(guān)的兼容性問(wèn)題的相當(dāng)詳細(xì)的概述。 我的觀點(diǎn)不是要涵蓋所有版??本中的所有這些問(wèn)題,而是要強(qiáng)調(diào)隨Java的每個(gè)主要發(fā)行版引入的一些關(guān)鍵的不兼容性問(wèn)題,這些問(wèn)題要么對(duì)我個(gè)人造成影響,要么對(duì)其他人產(chǎn)生更大影響。 這篇文章底部的鏈接提供給Sun / Oracle Java版本的兼容性文檔,以幫助那些尋求更大范圍的讀者。
升級(jí)
事后看來(lái),Java的這一早期發(fā)行版修復(fù)了實(shí)現(xiàn)與規(guī)范的一些不兼容性也就不足為奇了。 例如, JDK 1.2兼容性參考指出,在1.1版本中實(shí)現(xiàn)的String哈希函數(shù)與Java語(yǔ)言規(guī)范第一版中指定的函數(shù)不匹配,并且實(shí)際上是無(wú)法實(shí)現(xiàn)的。” 它補(bǔ)充說(shuō),“已實(shí)現(xiàn)的函數(shù)在某些類(lèi)別的字符串上執(zhí)行得非常差”,并解釋說(shuō),實(shí)現(xiàn)了“ 1.2版中新的String哈希函數(shù)”是為了“使實(shí)現(xiàn)符合規(guī)范并解決性能問(wèn)題。” 盡管可以預(yù)料到對(duì)String.hashCode()的更改不會(huì)影響大多數(shù)應(yīng)用程序,但是,人們公認(rèn)“具有依賴(lài)于實(shí)際String哈希值的持久性數(shù)據(jù)的應(yīng)用程序……理論上可能會(huì)受到影響。” 提醒您,依賴(lài)對(duì)象的hashCode()方法返回特定代碼通常不是一個(gè)好主意。
升級(jí)
JDK 1.3兼容性參考提到了一些更改,這些更改帶來(lái)了更多與JDK規(guī)范的實(shí)現(xiàn)一致性。 這樣的一個(gè)例子是引入了“類(lèi)型和子包之間的名稱(chēng)沖突”的更改:
根據(jù)…Java語(yǔ)言規(guī)范,…包中包含類(lèi)或接口類(lèi)型以及具有相同名稱(chēng)的子包是非法的。 在1.3版之前,幾乎從未執(zhí)行過(guò)此規(guī)則。 現(xiàn)在,新的編譯器將一致地執(zhí)行此規(guī)則。 如果在類(lèi)路徑或源路徑上可以訪問(wèn)相應(yīng)的目錄,源文件或類(lèi)文件,則不管其內(nèi)容如何,??都可以認(rèn)為包,類(lèi)或接口存在。
JDK 1.3還對(duì)“方法java.lang.Double.hashcode的實(shí)現(xiàn)”進(jìn)行了更改。
升級(jí)
由于JDK 1.4的更改,我在一個(gè)項(xiàng)目上升級(jí)到JDK 1.4的升級(jí)工作最終花費(fèi)的時(shí)間比估計(jì)的時(shí)間長(zhǎng),因此“編譯器現(xiàn)在拒絕從未命名空間中導(dǎo)入類(lèi)型的導(dǎo)入語(yǔ)句。” 換句話(huà)說(shuō),JDK 1.4取消了導(dǎo)入定義而無(wú)需顯式包的類(lèi)的功能。 我們沒(méi)有意識(shí)到這對(duì)我們來(lái)說(shuō)將是一個(gè)問(wèn)題,因?yàn)樗绊懙拇a是由第三方工具生成的代碼。 我們沒(méi)有控制代碼的生成以強(qiáng)制生成的類(lèi)位于命名包中,因此它們自動(dòng)成為“未命名名稱(chēng)空間”的一部分。 這意味著,使用JDK 1.4,我們將無(wú)法再將這些生成的類(lèi)與我們自己的源代碼一起編譯 。 發(fā)現(xiàn)并解決此更改花費(fèi)的時(shí)間比我們預(yù)期的要長(zhǎng),或者我們認(rèn)為這將是相對(duì)簡(jiǎn)單的JDK版本升級(jí)。 當(dāng)一個(gè)人控制代碼時(shí),同一JDK 1.4兼容性參考也指出了最合適的解決方案:“將所有類(lèi)從未命名的名稱(chēng)空間移到命名的名稱(chēng)空間。”
升級(jí)
我在上一篇文章“ 關(guān)于避免對(duì)toString()Result進(jìn)行解析或基于邏輯的美德”中寫(xiě)過(guò)Java SE 5對(duì)BigDecimal.toString()的更改。 Java SE 5兼容性參考只是指出:“ J2SE 5.0 BigDecimal的toString()方法的行為與早期版本不同。”
升級(jí)到Java SE 6時(shí),最讓我困擾的問(wèn)題是JDK 6中包含JAXB 。 Java SE 6兼容性參考中未列出此問(wèn)題,因?yàn)榇藛?wèn)題的性質(zhì)在技術(shù)上不符合此處記錄的兼容性問(wèn)題的定義。 但是,在遷移到Java SE 6之前使用單獨(dú)下載的JAXB JAR的任何人都可能遇到了我遇到的類(lèi)加載器問(wèn)題 。 我們大多數(shù)人過(guò)去用來(lái)解決此問(wèn)題的解決方案是將首選的JAXB JAR放置在指定的目錄中,該目錄是Java認(rèn)可的標(biāo)準(zhǔn)替代機(jī)制的一部分 ( 從Java 8開(kāi)始不推薦使用, 在Java 9中已刪除 )。
升級(jí)
升級(jí)到Java 7時(shí), com.sun.image.codec.jpeg軟件包的任何使用都被中斷。Java 7兼容性參考指出,“ com.sun.image.codec.jpeg軟件包已在JDK 1.2中添加(1998年12月)。作為控制JPEG格式圖像文件的加載和保存的非標(biāo)準(zhǔn)方式 。 該軟件包從不屬于平臺(tái)規(guī)范的一部分,已從Java SE 7發(fā)行版中刪除。 Java Image I / O API已作為標(biāo)準(zhǔn)API添加到JDK 1.4版本中,從而不再需要com.sun.image.codec.jpeg package 。”
Java 7中重新引入的另一個(gè)不兼容性實(shí)際上是使實(shí)現(xiàn)更好地符合規(guī)范的另一個(gè)示例。 在這種情況下,在Java SE 6中,具有基本相同的已刪除簽名但具有不同返回類(lèi)型的方法被視為兩種不同的方法。 這不符合規(guī)范,Java 7對(duì)此進(jìn)行了修復(fù)。 關(guān)于此問(wèn)題的更多詳細(xì)信息,請(qǐng)參見(jiàn)我的博客文章NetBeans 7.1的Internal Compiler和JDK 6尊重方法重載的返回類(lèi)型以及Java 7兼容性參考中 “摘要”標(biāo)題下的內(nèi)容:類(lèi)無(wú)法定義相同擦除的兩個(gè)方法簽名,但有兩種不同的返回類(lèi)型”和“編譯器不允許使用具有相同擦除簽名的非重寫(xiě)方法”。
Java 7升級(jí)也為Substance用戶(hù)帶來(lái)了一些困難。 非實(shí)質(zhì)性6.2版本的帖子指出:“ Java 7修復(fù)– Java的顏色選擇器中的一個(gè)錯(cuò)誤修復(fù)破壞了6.1的實(shí)質(zhì)。 這個(gè)問(wèn)題在Substance 6.2中已修復(fù),因此現(xiàn)在應(yīng)該可以在Java 7上運(yùn)行!” 破壞了Substance的JDK 7更改已在許多地方記錄,包括具有Substance外觀的JColorChooser,Java 7 , ColorChooser在具有JDK7的JSlider中導(dǎo)致NullPointerException以及顏色選擇器setColor在Java 7中不起作用 。
升級(jí)
就像Java 7的更改影響了實(shí)質(zhì)性的一樣,Java 8帶來(lái)的更改也直接影響了幾個(gè)流行且廣泛使用的Java庫(kù)。 盡管此更改可能直接影響了相對(duì)較少的Java應(yīng)用程序,但它間接地有可能影響許多Java應(yīng)用程序。 幸運(yùn)的是,這些Java庫(kù)的維護(hù)人員傾向于快速解決此問(wèn)題。 這是另一個(gè)實(shí)施規(guī)范的例子,該規(guī)范被嚴(yán)格化(更正)并破壞基于無(wú)法正確實(shí)施規(guī)范的實(shí)現(xiàn)而起作用的事物。 在這種情況下,更改/更正在字節(jié)碼驗(yàn)證程序中。 《 JDK 8兼容性指南》指出:“當(dāng)指令引用實(shí)例初始化方法(“ <init> ”)時(shí),invokespecial指令的驗(yàn)證已加強(qiáng)。 Niv Steingarten的博客文章Oracle最新的Java 8更新破壞了您的工具—它是如何發(fā)生的?
升級(jí)
Java 9似乎會(huì)引入一些重大的向后兼容性問(wèn)題 ,尤其是考慮到模塊化的引入。 雖然這些破損是什么尚待觀察,但最初的提議已經(jīng)引起了軒然大波 ,該提議取消了對(duì)sun.misc.Unsafe的訪問(wèn)。 這是另一個(gè)示例,其中官方不支持的API可能不會(huì)被大多數(shù)應(yīng)用程序直接使用,而是可能被眾多應(yīng)用程序間接使用 ,因?yàn)樗鼈円蕾?lài)的庫(kù)和產(chǎn)品都在使用它。 有趣的是,這引起了Mark Reinhold的提議 ,即將內(nèi)部API封裝在JDK 9中。考慮到與主要Java版本之間刪除和更改的內(nèi)部API相關(guān)的眾多兼容性問(wèn)題,這似乎是個(gè)好主意。
- 避免利用違反規(guī)范的不正確實(shí)現(xiàn),因?yàn)樵诟膶?shí)現(xiàn)以強(qiáng)制執(zhí)行規(guī)范時(shí),實(shí)現(xiàn)中的漏洞利用可能根本不起作用。
- 提防并謹(jǐn)慎使用任何宣傳為試驗(yàn)性或在將來(lái)的Java版本中刪除的API,類(lèi)和工具。 這包括sun。*軟件包以及不建議使用的工具和API。
- 我喜歡提議的“將內(nèi)部API封裝在JDK 9中”的JDK 9方法來(lái)解決主要版本升級(jí)中的這些常見(jiàn)問(wèn)題。
- 不要依賴(lài) toString()實(shí)現(xiàn)返回的String來(lái)實(shí)現(xiàn)程序邏輯。
結(jié)論
多年來(lái),為了保持Java在很大程度上向后兼容,已經(jīng)進(jìn)行了大量的努力。 但是,在某些情況下不能保持這種向后兼容性。 我在這篇文章中看了一些例子,并從這些例子中提取了一些觀察和教訓(xùn)。 當(dāng)開(kāi)發(fā)人員避免使用已棄用的功能,避免使用實(shí)驗(yàn)性功能以及避免使用非標(biāo)準(zhǔn)功能時(shí),向Java新版本的遷移往往會(huì)更容易。 此外,某些編碼實(shí)踐(例如避免將邏輯基于toString()結(jié)果)也可以提供幫助。
資源
- Oracle / Sun Java版本兼容性指南(按相反順序)
- JDK 8兼容性指南
- 其他相關(guān)資源
- 升級(jí)主要Java版本(7至8)
翻譯自: https://www.javacodegeeks.com/2016/06/observations-history-java-backwards-incompatibility.html
java向后兼容嗎
總結(jié)
以上是生活随笔為你收集整理的java向后兼容吗_Java向后不兼容历史的观察的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: jsf netbeans_NetBean
- 下一篇: java10个基础错误_我们处理了10亿