更新時間:2021-04-29 09:01:47 來源:動力節(jié)點 瀏覽1548次
為什么Java不支持多重繼承, 可以考慮以下兩點:
1)第一個原因是圍繞鉆石形繼承問題產(chǎn)生的歧義,考慮一個類 A 有 foo() 方法, 然后 B 和 C 派生自 A, 并且有自己的 foo() 實現(xiàn),現(xiàn)在 D 類使用多個繼承派生自 B 和C,如果我們只引用 foo(), 編譯器將無法決定它應(yīng)該調(diào)用哪個 foo()。
2)多重繼承確實使設(shè)計復(fù)雜化并在轉(zhuǎn)換、構(gòu)造函數(shù)鏈接等過程中產(chǎn)生問題。假設(shè)你需要多重繼承的情況并不多,簡單起見,明智的決定是省略它。此外,Java 可以通過使用接口支持單繼承來避免這種歧義。由于接口只有方法聲明而且沒有提供任何實現(xiàn),因此只有一個特定方法的實現(xiàn),因此不會有任何歧義。
1)簡單性和清晰性。清晰性是Java設(shè)計者的目標(biāo)之一。設(shè)計者不是只想復(fù)制語言,而是希望擁有一種清晰,真正面向?qū)ο蟮恼Z言。添加運算符重載比沒有它肯定會使設(shè)計更復(fù)雜,并且它可能導(dǎo)致更復(fù)雜的編譯器, 或減慢 JVM,因為它需要做額外的工作來識別運算符的實際含義,并減少優(yōu)化的機會, 以保證 Java 中運算符的行為。
2)避免編程錯誤。Java 不允許用戶定義的運算符重載,因為如果允許程序員進行運算符重載,將為同一運算符賦予多種含義,這將使任何開發(fā)人員的學(xué)習(xí)曲線變得陡峭,事情變得更加混亂。據(jù)觀察,當(dāng)語言支持運算符重載時,編程錯誤會增加,從而增加了開發(fā)和交付時間。由于 Java 和 JVM 已經(jīng)承擔(dān)了大多數(shù)開發(fā)人員的責(zé)任,如在通過提供垃圾收集器進行內(nèi)存管理時,因為這個功能增加污染代碼的機會, 成為編程錯誤之源, 因此沒有多大意義。
3)JVM復(fù)雜性。從JVM的角度來看,支持運算符重載使問題變得更加困難。通過更直觀,更干凈的方式使用方法重載也能實現(xiàn)同樣的事情,因此不支持 Java 中的運算符重載是有意義的。與相對簡單的 JVM 相比,復(fù)雜的 JVM 可能導(dǎo)致 JVM 更慢,并為保證在 Java 中運算符行為的確定性從而減少了優(yōu)化代碼的機會。
4)讓開發(fā)工具處理更容易。這是在 Java 中不支持運算符重載的另一個好處。省略運算符重載使語言更容易處理,這反過來又更容易開發(fā)處理語言的工具,例如 IDE 或重構(gòu)工具。Java 中的重構(gòu)工具遠(yuǎn)勝于 C++。
字符串:1)由于字符串在 Java 中是不可變的,如果你將密碼存儲為純文本,它將在內(nèi)存中可用,直到垃圾收集器清除它. 并且為了可重用性,會存在 String 在字符串池中, 它很可能會保留在內(nèi)存中持續(xù)很長時間,從而構(gòu)成安全威脅。
由于任何有權(quán)訪問內(nèi)存轉(zhuǎn)儲的人都可以以明文形式找到密碼,這是另一個原因,你應(yīng)該始終使用加密密碼而不是純文本。由于字符串是不可變的,所以不能更改字符串的內(nèi)容,因為任何更改都會產(chǎn)生新的字符串,而如果你使用char[],你就可以將所有元素設(shè)置為空白或零。因此,在字符數(shù)組中存儲密碼可以明顯降低竊取密碼的安全風(fēng)險。
2)Java 本身建議使用 JPasswordField 的 getPassword() 方法,該方法返回一個 char[] 和不推薦使用的getTex() 方法,該方法以明文形式返回密碼,由于安全原因。應(yīng)遵循 Java 團隊的建議, 堅持標(biāo)準(zhǔn)而不是反對它。
3)使用 String 時,總是存在在日志文件或控制臺中打印純文本的風(fēng)險,但如果使用 Array,則不會打印數(shù)組的內(nèi)容而是打印其內(nèi)存位置。雖然不是一個真正的原因,但仍然有道理。
序列化是把對象改成可以存到磁盤或通過網(wǎng)絡(luò)發(fā)送到其他運行中的 Java 虛擬機的二進制格式的過程, 并可以通過反序列化恢復(fù)對象狀態(tài). Java 序列化API給開發(fā)人員提供了一個標(biāo)準(zhǔn)機制, 通過 java.io.Serializable 和 java.io.Externalizable 接口, ObjectInputStream 及ObjectOutputStream 處理對象序列化. Java 程序員可自由選擇基于類結(jié)構(gòu)的標(biāo)準(zhǔn)序列化或是他們自定義的二進制格式, 通常認(rèn)為后者才是最佳實踐, 因為序列化的二進制文件格式成為類輸出 API的一部分, 可能破壞 Java 中私有和包可見的屬性的封裝.
不能覆蓋Java中的靜態(tài)方法,因為方法覆蓋基于運行時的動態(tài)綁定,靜態(tài)方法在編譯時使用靜態(tài)綁定進行綁定。雖然可以在子類中聲明一個具有相同名稱和方法簽名的方法,看起來可以在Java中覆蓋靜態(tài)方法,但實際上這是方法隱藏。Java不會在運行時解析方法調(diào)用,并且根據(jù)用于調(diào)用靜態(tài)方法的 Object 類型,將調(diào)用相應(yīng)的方法。這意味著如果你使用父類的類型來調(diào)用靜態(tài)方法,那么原始靜態(tài)將從父類中調(diào)用,另一方面如果你使用子類的類型來調(diào)用靜態(tài)方法,則會調(diào)用來自子類的方法。簡而言之,你無法在Java中覆蓋靜態(tài)方法。如果你使用像Eclipse或Netbeans這樣的Java IDE,它們將顯示警告靜態(tài)方法應(yīng)該使用類名而不是使用對象來調(diào)用,因為靜態(tài)方法不能在Java中重寫。
以上就是動力節(jié)點小編介紹的”高級Java面試題及答案”的內(nèi)容,希望對大家有幫助,如有疑問,請在線咨詢,有專業(yè)老師隨時為您服務(wù)。