2011-04-19 102 views
3

是否有可能將諸如Groovy,Scala之類的JVM語言反編譯爲其初始形式?反編譯JVM語言

如果我嘗試反編譯4行Groovy類,我會得到約20行反編譯的Java代碼。

這是一個比實際問題更多的理論問題,因爲市場上沒有這樣的反編譯器(不是我所知道的)。

謝謝。

+0

請注意,編譯器_will_丟棄無法重構的信息,因此您永遠無法獲得原始的信息。 – 2015-10-23 14:24:01

回答

3

是的,它可能具有Java反編譯器可以管理的類似保真度(意思是:代碼看起來相似,但不一定完全相同)。

但是,您需要針對每種語言的專用反編譯器。

編輯:我想我需要澄清我所期望的水平保真度:

  • 局部變量的名稱可能是也可能不是可重放
  • 循環類型可能被錯誤地解釋(for通過while,...)
  • 更一般的更換:事情,可以在兩個類似的方式來完成可能是錯誤解釋
  • ...

所有這些都是在反編譯Java代碼時也會出現的錯誤,僅僅是因爲從字節碼到Java源代碼的關聯不是1:1。

不過,如果你有一個專門的Groovy的反編譯器,那麼我強烈懷疑它以從反編譯更可讀的代碼編譯的Groovy代碼比一個Java反編譯器都做不到。

+0

的確是一個非常樂觀的假設。 – Ingo 2011-04-20 14:06:35

+0

@Ingo:我不明白這是樂觀的。由合格的Java反編譯器生成的代碼只與原始源代碼具有基本相似性。局部變量名稱通常會丟失(除非在編譯過程中明確包含在'.class'文件中),並且通常使用的特定類型的循環也被錯誤地表示(用'while循環替換'for循環)。 – 2011-04-20 14:08:00

+1

我在我的文章中闡述了nmy的不同觀點。 – Ingo 2011-04-20 14:10:27

0

那麼,我能想到的唯一的事情就是編譯器優化和評論的問題。字節碼中沒有保留註釋(幸好),編譯器可能會改變源代碼以獲得更好的性能,除此之外它似乎是可能的。

+0

我不擔心評論。但你怎麼會恢復這樣的東西? this.metaClass =((MetaClass)ScriptBytecodeAdapter.castToType(tmp12_9,$ get $$ class $ groovy $ lang $ MetaClass())); tmp12_9; while(true) return; – 2011-04-19 21:15:49

+2

@Alexandru:這不是字節碼。這就是Java語言反編譯器**試圖解釋不是通過編譯Java語言代碼而產生的字節碼的方式。這必然會產生奇怪的結果,但是對於正確語言的專用反編譯器會識別「奇怪」的字節碼結構並知道它表示的是什麼語言結構。 – 2011-04-20 13:33:55

+0

@Joachim,你是對的,這不是字節碼,這就是爲什麼我沒有說它是。我想這是有道理的,如果你知道你正在處理一個Groovy生成的類文件,你應該知道你必須處理它與Java生成的類文件不同。 – 2011-04-20 14:46:22

1

這不一定可能。例如,一種語言可能會以不可逆的方式破壞它的名字。此外,它可以將源語言的不同結構映射到單個Java語言結構。

然而,最重要的是,java語言(與JVM字節碼相比)不能夠強大到足以對源語言的某些概念或結構進行編碼,使得它們可以被通用化。 Java和JVM字節碼就是這種情況,後者不能表達泛型。

+0

您的第二點,我不是故意將由Groovy生成的Java字節碼轉換回Java,而是轉回到Groovy。 – 2011-04-20 15:32:23

+0

@Alexandru - 多數民衆贊成在我的意思 - 我不知道Groovy,但可以想象,它具有某些功能,不能被編譯爲字節碼,而不會丟失信息。具有諷刺意味的是,當編譯爲字節碼時,信息丟失的一種語言的一個例子是Java本身,因此可以肯定地認爲,其他語言的情況會更多。 – Ingo 2011-04-20 17:26:21