2010-04-07 85 views
19

最近我開始使用Eclipse的java編譯器,因爲它比標準的javac快得多。我被告知它更快,因爲它執行增量編譯。但是我仍然有點不確定,因爲我找不到關於這兩者的權威性文檔 - eclispse和sun's - 編譯器「增量特性」。 Sun的編譯器是否總是編譯每個源文件並且Eclipse的編譯器僅編譯已更改的文件以及受此類更改影響的文件?標準的Sun javac可以進行增量編譯嗎?

編輯:我不使用Eclipse的自動構建功能,而是我設置

-Dbuild.compiler=org.eclipse.jdt.core.JDTCompilerAdapter 

我的螞蟻構建。

+1

Oracle已經努力用'sjavac'工具來解決這個問題。相關問題:http://stackoverflow.com/questions/26424759/what-is-sjavac-who-is-it-for-and-how-do-i-use-it – aioobe 2014-10-29 14:43:19

回答

14

這是真的,Sun的編譯器總是編譯所有的源文件和Eclipse的編譯器編譯只改文件和那些受影響的文件通過這樣的改變?

我相信你在兩方面都是正確的。

你當然可以強制Eclipse重新編譯一切。

但等式的另一部分是Java構建工具(如Ant和Maven)只能編譯已更改的類以及它們的依賴類樹。

編輯

在螞蟻,漸進式編譯可以通過兩種方式來完成:

  • 默認情況下,<javac> task.java相應.class文件的時間戳和進行比較,只告訴Java編譯器重新編譯比相應的目標(.class)文件更新或者根本沒有目標文件的源文件(.java)。

  • <depend> task還考慮了類之間的依賴關係,它通過讀取和分析嵌入在.class文件中的依賴性信息來確定。確定哪些.class文件已過期後,<depend>任務將刪除它們,以便以下<javac>任務將重新編譯它們。但是,這並非完全可以證明的。例如,對源代碼進行大量更改可能會導致<depend>任務可能正在分析陳舊的依賴關係。還有某些種類的依賴關係(例如靜態常量)在.class文件格式中並不明顯。

    要理解爲什麼Ant <depend>不是防呆的,請閱讀documentation的「限制」部分。

+0

你能解釋一下如何用Ant部分編譯工作? Ant如何強制Sun的編譯器僅編譯已更改的文件並忽略源代碼樹中的其他文件? – 2010-04-07 11:12:16

+0

我想你回答了我原來的問題,但是當你提供更多信息時,我越來越困惑。如果我理解正確,在我看來,javac任務沒有以前的清理是非常危險的操作,因爲如果他們的時間戳沒有改變,它不編譯相關的類。 (有趣的是,我只是意識到我昨天有過這個問題,看起來對我來說完全是個謎。) – 2010-04-07 12:22:35

+0

爲什麼你需要編譯一個依賴類,如果它沒有改變? – 2010-12-04 01:13:57

2

Eclipse肯定會這樣做。如果你打開了這個選項(它是默認的),它也可以在保存時進行。它看起來像太陽也不會這樣做(這很容易測試,只是做一個小項目,其中A是使用類B的主類,但B不使用類A.然後更改A並編譯項目再看看b.class的時間戳是否發生了變化

這是許多編譯器工作的方式(例如gcc),你可以使用像ant和make這樣的工具來編譯只改變項目的部分。這些工具是不完美的,有時偏食剛失去的變化軌跡,你需要做一個全面的重建。

3

Javac只編譯在命令行中命名的或者是依賴關係且已過期的源文件。 Eclipse可能會用更細緻的方式來決定這意味着什麼。

+0

你能鏈接一些支持這個答案的文檔嗎?我認爲1)依賴不是由純javac編譯的,2)Eclipse有它自己的,完全不同的編譯器,而不僅僅是更細緻的決定方式。我無法證明這一點,但這就是爲什麼我問:)... – 2010-12-08 20:37:36

+0

http://download.oracle.com/javase/6/docs/technotes/tools/windows/javac.html#searching。當然你可以證明這一點:只要設定我描述的條件,你就會看到自己。 – EJP 2010-12-09 07:00:00

+0

這是正確的:javac編譯你告訴它編譯的文件,而不是「每個源文件」。它不會自行決定哪些文件需要編譯,因此在OP所詢問的意義上它不是遞增的。進一步的(正如EJP所說),當javac正在編譯class A並且發現A依賴的其他.java文件時,它(取決於許多因素)也編譯它們。這與查找可能受到A.java更改影響的文件不同,我認爲這就是人們感到困惑的地方。 – gatkin 2012-03-26 23:43:00

2

重申發佈我在這裏聽到造句它懶惰的人喜歡我:

可以實現增量構建與螞蟻javac任務,但你應該使用取決於任務,以清除.class文件的你的修改過的.java和你不能在javac任務中沒有指定includes語句。 (在javac任務中只指定src路徑並保留包含未指定的原因導致javac重新編譯它找到的所有源。)

這裏是我的依賴和javac任務。使用標準的Oracle java編譯器,我只修改了.java文件。希望這可以幫助!

<depend srcdir="JavaSource" destdir="${target.classes}" cache="${dependencies.dir}" closure="yes"> 
    <classpath refid="compiler.classpath" /> 
    <include name="**/*.java"/> 
</depend> 

<javac destdir="${target.classes}" debug="true" debuglevel="${debug.features}" optimize="${optimize.flag}" fork="yes" deprecation="no" source="1.6" target="1.6" encoding="UTF-8" includeantruntime="no"> 
    <classpath refid="compiler.classpath"/> 
    <src path="JavaSource"/> 
    <include name="**/*.java" /> <!-- This enables the incremental build --> 
</javac> 
相關問題