亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如果對具體類進行更改,是否依賴于接口而不是具體類會減少 Java 中的編譯時間?

如果對具體類進行更改,是否依賴于接口而不是具體類會減少 Java 中的編譯時間?

LEATH 2021-11-17 15:11:47
我正在閱讀 Michael Feathers 的“Working Effectively with Legacy Code”,在一個子主題“打破依賴關系”中提到,如果一個類依賴于一個接口,那么如果對具體實現進行了更改,則原始依賴類不會不必再次編譯,因為您不直接依賴于實現。本書章節供參考:https : //www.safaribooksonline.com/library/view/working-effectively-with/0131177052/ch07.html我同意這一點,但是在 Java 中觀察到的這種變化是否在編譯時間上有顯著差異,或者這在 C++ 的上下文中是否更相關?我閱讀了 C++ 中用于提供編譯時優化的 PIMPL 模式或橋接模式,但在 JAVA 中也可以實現相同的功能,還是 Java 編譯器自己進行這種優化?
查看完整描述

3 回答

?
慕虎7371278

TA貢獻1802條經驗 獲得超4個贊

我從未將編譯時間視為 Java 中的設計考慮因素(從 v 1 開始使用 Java)。具體到您的問題,語言規范在這方面沒有提供任何保證。它可能會因版本和實現而異。


在 javac 之外,構建系統可能會做明智的事情,例如參見:https : //blog.gradle.org/incremental-compiler-avoidance


編輯:只需仔細檢查,即使沒有更改,也要javac重新編譯源:


$ java -version

openjdk version "10.0.2" 2018-07-17


$ javac *.java && ls -l A.*

-rw-rw-r-- 1 usr usr 143 Oct 14 20:07 A.class

-rw-rw-r-- 1 usr usr  59 Oct 14 19:57 A.java

等了一分鐘后...


$ javac *.java && ls -l A.*

-rw-rw-r-- 1 usr usr 143 Oct 14 20:08 A.class

-rw-rw-r-- 1 usr usr  59 Oct 14 19:57 A.java


查看完整回答
反對 回復 2021-11-17
?
素胚勾勒不出你

TA貢獻1827條經驗 獲得超9個贊

不,沒有顯著差異。大部分編譯時間都在解析,這完全不受此影響。

重點是:給定文件'MySource.java',包含某種類型的MySource,如果MySource 的任何父類型被重新定義,你真的應該重新編譯這個類。你不必,java會盡力而為,但現在你可以創造瘋狂的場景(例如,如果你更新父類型來添加一個新的抽象方法,就像一個必須實現的方法,現在你仍然有一個沒有的子類型。當您嘗試混合由不同的編譯運行生成的這些類時,會拋出運行時錯誤)。

使用接口的重點是避免它:即使具體實現確實發生了變化,也有一個根本沒有改變的超類型(沒有人接觸過接口定義)。

你會認為這意味著:嘿,太好了,現在我什至不必重新編譯這個文件。但這并不重要。與 C 語言相比,java 編譯時間非??欤ㄖ恍鑾酌腌娂纯赏瓿纱罅宽椖浚?,而且很難有一個足夠智能的構建系統來意識到在這種情況下不需要重新編譯。不; 關鍵是有點自我控制:如果你有一個拆分項目,其中接口/父類在源代碼庫 A 中,而子類在 B 中,事情就會中斷:除非 A 和 B 由相同的人維護人和重建同時,你有問題。

因此,重點是:您擁有“公共 API”,例如,除非您有充分的理由,否則不得更改您規定的類型。使接口更明確哪些位不會改變。這使源代碼庫 A 的作者可以自由更改(非公共/導出)實現類,只要他們不弄亂接口,而不必去調用源代碼庫 B 的優秀人員并告訴他們: 呃,抱歉,我們改變了一些東西,你必須做一個完整的重建。



查看完整回答
反對 回復 2021-11-17
?
九州編程

TA貢獻1785條經驗 獲得超4個贊

如果更改具體類,則只需要重新編譯具體類及其調用者。如果您有一個接口,并且人們正在調用接口而不是具體類,那么他們不會被視為具體類的調用者,也不需要重新編譯。這是接口幫助減少編譯時間的唯一方法,AFAICT。

每個對接口進行類型優化的 Java 實現都將該優化推遲到運行時 (HotSpot) 優化器:有關更多信息,您正在尋找的術語是“專業化”。Java 編譯器本身(即:Java => 字節碼編譯器)實際上幾乎沒有進行優化,并且由于無法在運行時對代碼進行推理(參見:Haskell 的編譯器)而受到阻礙。這是因為您可以進行動態代碼加載:可以在運行時通過類路徑修改和反射來更改接口的可能實現集。


查看完整回答
反對 回復 2021-11-17
  • 3 回答
  • 0 關注
  • 206 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號