Java 9中什么是私有的?
在進行面試時,我發現大多數應聘者都不知道Java中的private修飾符真正意味著什么。 他們知道一些足以進行日常編碼的事情,但還遠遠不夠。 這不成問題。 足夠了解就足夠了。 但是,了解Java的一些內部工作仍然很有趣。 在極少數情況下,它可能會揭示某些細節。 如果沒有別的,那就很有趣.orElse(whyDoYouReadIt) ?
順便說一句:在我看來,即使與我個人有關的陳述和含義是虛假的,提及面談也是寫評委的好機會。 畢竟,我這個人并不重要,并且遠離批評我的事實,我發現這篇文章很有趣,關于訪談的結論很重要,實際上完全符合我的觀點。
本文希望以比閱讀語言標準更具可讀性的方式描述一些Java事實。
那么什么是私人的?
private是Java中的訪問修飾符。 如果您具有某個類的private成員(方法,字段,內部或嵌套類或嵌套接口),則該類只能由同一類中的代碼使用。 有趣的問題是:當private方法包含多個類時,會發生什么? 怎么可能不止一個班? 如果有一個包含另一個類的類,并且在內部/嵌套類內部有一個private方法,則它在內部/嵌套類內部以及頂級類中。
封閉類內部的私有方法可以從外部類調用嗎? 封閉類中的代碼可以在外部類中調用私有方法嗎? 在兩種情況下答案都是肯定的。 樣例代碼
package javax0.package1;class TopLevelClass {void topMethod(){NestedClass nc = new NestedClass();nc.method();}private int z;interface NestedInterface {default void method(){TopLevelClass tlc = new TopLevelClass();tlc.z++;}}static class NestedClass {private int k;private void method() {TopLevelClass tlc = new TopLevelClass();k = tlc.z;}} }清楚地顯示了這種情況:嵌套類NestedClass和嵌套接口NestedInterface都包含可以訪問包含private字段z的外部類的代碼。 同樣,頂級類代碼可以在嵌套類內部調用私有方法。 在這種情況下,此示例代碼實際上并未執行任何合理的操作并不重要。
如果我們編譯此單個源文件,則會得到三個類文件:
那是因為JVM不知道什么是頂層和嵌套的。 JVM對嵌套類和頂級類一無所知。 對于JVM,類只是一個類。 如果您堅持的話,要參加頂級課程。 這主要是因為Java語言1.0沒有嵌套類和內部類,并且JVM是根據該類設計的。 在Java 1.1中引入內部類和嵌套類時,僅修改了編譯而不是JVM,因此內部類和嵌套類仍然是語言功能,但不能直接由JVM處理。
頂級類如何訪問嵌套在源代碼中的另一個類中的私有方法,但是在編譯時,它只是另一個“頂級”類。 它們處于同一級別。 如果將可訪問性更改為公共,那么我們也可以從其他類中訪問它,但我們不能。 編譯器將不允許其他類中的任何其他代碼訪問私有方法,即使我們做了一些技巧來克服編譯器,生成的類填充也將使JVM引發異常。 Java中的私有是私有的。
真正發生的是,編譯器生成了特殊的getter和setter方法來訪問字段z 。
將為從同一頂級類內部的不同類訪問的每個私有字段或方法創建一個橋接方法。 如果未從封閉類訪問私有對象,則不會生成該方法。 如果僅讀取該字段,則僅生成getter;如果僅從外部進行設置,則僅生成setter。
這也是一個有趣的失敗,因為認為只能從同一對象內訪問私有字段(或其他任何內容)。 這是我們在編程時使用這些成員的通常方式,但是如果代碼具有對相同類型另一個實例的引用,則通過該引用,我們可以訪問其他對象的私有字段,就像訪問“我們的對象”一樣好。自己的”字段。 這是罕見的情況嗎? 您可能會想,因為您很少對其進行編程。 但是實際上它非常頻繁:IDE通常為我們生成代碼,這就是為什么某些開發人員不考慮這一點的原因。 沒有這個,幾乎不可能對類的equals(Object other)方法進行編碼。
Java 9呢?
到目前為止,本文中沒有關于Java 9的特定內容,而如今,每一篇Java文章都應該涉及Java 9(或已經是10)了。
如果我們一般地看一下訪問控制,那么我們就不得不談論JPMS,并且有很多關于此的文章。 codeFx上有很好的文章清單。 Stephen Colebourne的文章不錯。
很快,您甚至可以從不同的出版商那里購買有關Java模塊系統的書籍。 我很幸運,我已經可以閱讀Packt的草稿,成為審稿人,我很喜歡。 但是,JPMS不會在此級別上更改“私有”。 仍然會有嵌套類,內部類和橋接方法,它們與以前完全相同。
幾乎沒有什么不同,Java 9現在在接口內部具有私有方法。 這意味著現在我們應該準備在內部和嵌套類中以及在接口中都具有合成橋方法。
起飛...
有時候最簡單的事情并不像看起來那樣簡單。 畢竟,整個IT技術,科學和工程都不過是一堆零和一。 只是我們有很多。 真的很多 如果本文對您來說是新的內容,那么它應該告訴您Java語言和JVM中的某些領域您可能有興趣研究更多。 例如:
- 嵌套類和內部類之間有什么區別?
- 您可以在類內部有一個嵌套接口,而在類內部也可以有一個內部接口?
- 接口中的類或接口呢? 接口中可以有內部類嗎? 嵌套類怎么樣?
- 您可以使用反射來編寫列出類所有方法的代碼嗎? 會列出合成方法嗎? 它會具有哪些修飾符?
- 編譯內部類時,它將具有已編譯名稱Outer$Inner.class ,這是一個合法名稱。 但是,如果有Outer$Inner.java源文件會發生什么? 想辦法!
- 生成的合成方法也具有合法名稱。 如果使用該名稱定義方法會怎樣? 您看到的是Java規范還是特定于實現的?
- 您可以嵌套內部和嵌套的類和/或接口有多深? 嵌套類可以包含內部類嗎? 內部類可以包含嵌套類嗎?
- 您怎么猜,為什么JDK中沒有合成修飾符的符號名? 為什么修改器的實際值與volatile字段的值相同?
- 嵌套類中可以有一個靜態字段,類或方法嗎?
我知道,這些問題和知識的答案不切實際。 我從未見過任何代碼或項目,這些代碼或項目知道內部類不能具有靜態字段會帶來任何好處。 另一方面,考慮這些問題,獲得答案可能會給您帶來一些快樂,例如解決填字游戲(如果您喜歡的話)以及仍然有用的知識,以我們無法識別的方式幫助理解技術。 在某些情況下,一個人發現錯誤的速度比其他人快,因為她“感覺”到該技術。 那是當您無法說出是什么在耳邊竊竊私語時,卻是像上面那樣的知識。 但是,只有當您喜歡深入研究該技術的那些細微之處時,才會如此。
最后一個技巧性的問題,如果您愿意,甚至比上面的娛樂問題還不如上面的實用:
難題
我們知道,內部(非嵌套)類內部不可能有靜態字段。 仍然有可能由Java編譯器從具有靜態方法的內部類生成編譯的類文件嗎?
翻譯自: https://www.javacodegeeks.com/2017/08/private-java-9.html
總結
以上是生活随笔為你收集整理的Java 9中什么是私有的?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MQTT网关如何接入华为云华为路由器如何
- 下一篇: 电脑怎么保存网页到桌面上使用电脑如何保存