成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

javap命令與Java Dcompiler工具、IDEA自帶的反編譯器反編譯的結(jié)果的差別及原因

張憲坤 / 1045人閱讀

摘要:反匯編器與反編譯器不同,反編譯器的目標(biāo)是高級(jí)語(yǔ)言而非匯編語(yǔ)言。反匯編器的反匯編輸出通常格式化為適合人類閱讀,而非用作匯編器的輸入源,因此它主要是一個(gè)逆向工程工具。本文章參考了通過(guò)命令分析匯編指令反匯編器

問(wèn)題描述

寫(xiě)這篇文章是為了記錄我這幾天遇到的一個(gè)疑惑,并且順藤摸瓜的學(xué)習(xí)一下javap命令。遇到的疑惑是這樣的:我在看“使用枚舉類型實(shí)現(xiàn)單列模式”的博客時(shí),發(fā)現(xiàn)一些博客中寫(xiě)到的枚舉類型的反編譯結(jié)果包含的信息不盡相同:
??一些對(duì)枚舉類的反編譯結(jié)果僅僅包含像我們正常編寫(xiě)的枚舉類的一些信息,如使用IDEA,Java Decompiler;
??而另一些反編譯結(jié)果則完全不同:一方面枚舉類成為了普通的class類,只是它繼承了Enum類,枚舉值都是public static final形式的對(duì)象;另一方面還多了static塊,values(),valueof()這些方法。

源代碼:

public enum Season {
    SPIRNG,
    SUMMER,
    AUTUMN,
    WINTER;

    public String allSeasons() {
        return SPIRNG.name() + " " + SUMMER.name() + " " + AUTUMN.name() +" " +WINTER.name();
    }
}

使用javap -c Season.class命令反編譯結(jié)果:

public final class Season extends java.lang.Enum {
  public static final Season SPIRNG;

  public static final Season SUMMER;

  public static final Season AUTUMN;

  public static final Season WINTER;

  public static Season[] values();
    Code:
       0: getstatic     #1                  // Field $VALUES:[LSeason;
       3: invokevirtual #2                  // Method "[LSeason;".clone:()Ljava/lang/Object;
       6: checkcast     #3                  // class "[LSeason;"
       9: areturn

  public static Season valueOf(java.lang.String);
    Code:
       0: ldc           #4                  // class Season
       2: aload_0
       3: invokestatic  #5                  // Method java/lang/Enum.valueOf:(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;
       6: checkcast     #4                  // class Season
       9: areturn

  public java.lang.String allSeasons();
    Code:
       0: new           #7                  // class java/lang/StringBuilder
       3: dup
       4: invokespecial #8                  // Method java/lang/StringBuilder."":()V
       7: getstatic     #9                  // Field SPIRNG:LSeason;
      10: invokevirtual #10                 // Method name:()Ljava/lang/String;
      13: invokevirtual #11                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      16: ldc           #12                 // String
      18: invokevirtual #11                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      21: getstatic     #13                 // Field SUMMER:LSeason;
      24: invokevirtual #10                 // Method name:()Ljava/lang/String;
      27: invokevirtual #11                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      30: ldc           #12                 // String
      32: invokevirtual #11                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      35: getstatic     #14                 // Field AUTUMN:LSeason;
      38: invokevirtual #10                 // Method name:()Ljava/lang/String;
      41: invokevirtual #11                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      44: ldc           #12                 // String
      46: invokevirtual #11                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      49: getstatic     #15                 // Field WINTER:LSeason;
      52: invokevirtual #10                 // Method name:()Ljava/lang/String;
      55: invokevirtual #11                 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
      58: invokevirtual #16                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
      61: areturn

  static {};
    Code:
       0: new           #4                  // class Season
       3: dup
       4: ldc           #17                 // String SPIRNG
       6: iconst_0
       7: invokespecial #18                 // Method "":(Ljava/lang/String;I)V
      10: putstatic     #9                  // Field SPIRNG:LSeason;
      13: new           #4                  // class Season
      16: dup
      17: ldc           #19                 // String SUMMER
      19: iconst_1
      20: invokespecial #18                 // Method "":(Ljava/lang/String;I)V
      23: putstatic     #13                 // Field SUMMER:LSeason;
      26: new           #4                  // class Season
      29: dup
      30: ldc           #20                 // String AUTUMN
      32: iconst_2
      33: invokespecial #18                 // Method "":(Ljava/lang/String;I)V
      36: putstatic     #14                 // Field AUTUMN:LSeason;
      39: new           #4                  // class Season
      42: dup
      43: ldc           #21                 // String WINTER
      45: iconst_3
      46: invokespecial #18                 // Method "":(Ljava/lang/String;I)V
      49: putstatic     #15                 // Field WINTER:LSeason;
      52: iconst_4
      53: anewarray     #4                  // class Season
      56: dup
      57: iconst_0
      58: getstatic     #9                  // Field SPIRNG:LSeason;
      61: aastore
      62: dup
      63: iconst_1
      64: getstatic     #13                 // Field SUMMER:LSeason;
      67: aastore
      68: dup
      69: iconst_2
      70: getstatic     #14                 // Field AUTUMN:LSeason;
      73: aastore
      74: dup
      75: iconst_3
      76: getstatic     #15                 // Field WINTER:LSeason;
      79: aastore
      80: putstatic     #1                  // Field $VALUES:[LSeason;
      83: return
}

使用Java Decompiler工具的反編譯結(jié)果:

public enum Season
{
  SPIRNG,  SUMMER,  AUTUMN,  WINTER;
  
  private Season() {}
  
  public String allSeasons()
  {
    return SPIRNG.name() + " " + SUMMER.name() + " " + AUTUMN.name() + " " + WINTER.name();
  }
}

從上面反編譯的結(jié)果我們總結(jié)差別如下

javap反編譯的結(jié)果中類的聲明不同,它是一個(gè)繼承了Enum類并且聲明為final類型的類;

javap反編譯結(jié)果中包含的方法不同,它包含了static(),valueOf(),values()方法;

javap反編譯結(jié)果中的方法體不同,它的方法體使用jvm指令來(lái)描述。

javap命令
C:Usersw00457192>javap -h
用法: javap  
其中, 可能的選項(xiàng)包括:
  -? -h --help -help               輸出此幫助消息
  -version                         版本信息
  -v  -verbose                     輸出附加信息
  -l                               輸出行號(hào)和本地變量表
  -public                          僅顯示公共類和成員
  -protected                       顯示受保護(hù)的/公共類和成員
  -package                         顯示程序包/受保護(hù)的/公共類和成員 (默認(rèn))
  -p  -private                     顯示所有類和成員
  -c                               對(duì)代碼進(jìn)行反匯編
  -s                               輸出內(nèi)部類型簽名
  -sysinfo                         顯示正在處理的類的系統(tǒng)信息 (路徑, 大小, 日期, MD5 散列)
  -constants                       顯示最終常量
  --module <模塊>, -m <模塊>       指定包含要反匯編的類的模塊
  --module-path <路徑>             指定查找應(yīng)用程序模塊的位置
  --system                    指定查找系統(tǒng)模塊的位置
  --class-path <路徑>              指定查找用戶類文件的位置
  -classpath <路徑>                指定查找用戶類文件的位置
  -cp <路徑>                       指定查找用戶類文件的位置
  -bootclasspath <路徑>            覆蓋引導(dǎo)類文件的位置

從上面的信息我們可以看出javap -c是用于反匯編,而不是反編譯。參考維基百科的解釋如下:

反匯編器(disassembler)是一種將機(jī)器語(yǔ)言轉(zhuǎn)換為匯編語(yǔ)言的計(jì)算機(jī)程序——這與匯編器的目的相反。反匯編器與反編譯器不同,反編譯器的目標(biāo)是高級(jí)語(yǔ)言而非匯編語(yǔ)言。反匯編器的反匯編輸出通常格式化為適合人類閱讀,而非用作匯編器的輸入源,因此它主要是一個(gè)逆向工程工具。
結(jié)論

現(xiàn)在我們可以理解為什么javap和Java Decompiler的輸出中方法體有所不同了。

至于為什么Java Decompiler沒(méi)有包含static塊和values(),valueof()方法,我推測(cè)是因?yàn)榉淳幾g器的目的是反編譯出源碼,而我們可以確定的是static塊和values()和valueof()這兩個(gè)方法是編譯器自己實(shí)現(xiàn)的,不是我們?nèi)藶樘砑拥?,所以在反編譯器看來(lái)這不屬于源碼的一部分,因此沒(méi)有在編譯的結(jié)果中包含這些方法。

本文章參考了
??通過(guò)javap命令分析java匯編指令
??反匯編器

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/77697.html

相關(guān)文章

  • JAVA語(yǔ)法糖和語(yǔ)法糖編譯

    摘要:提供給了用戶大量的語(yǔ)法糖,比如泛型自動(dòng)裝箱拆箱循環(huán)變長(zhǎng)參數(shù)內(nèi)部類枚舉類斷言新特性方法引用等解語(yǔ)法糖語(yǔ)法糖的存在主要是方便開(kāi)發(fā)人員使用。 首先,部分總結(jié)文字引用 簡(jiǎn)書(shū)作者:Eric新之助 。鏈接:https://www.jianshu.com/p/4de08deb6ba4 已獲得授權(quán) showImg(https://segmentfault.com/img/bVbfuX9?w=646&...

    weakish 評(píng)論0 收藏0
  • Javag工程師成神之路(2019正式版)

    摘要:結(jié)構(gòu)型模式適配器模式橋接模式裝飾模式組合模式外觀模式享元模式代理模式。行為型模式模版方法模式命令模式迭代器模式觀察者模式中介者模式備忘錄模式解釋器模式模式狀態(tài)模式策略模式職責(zé)鏈模式責(zé)任鏈模式訪問(wèn)者模式。 主要版本 更新時(shí)間 備注 v1.0 2015-08-01 首次發(fā)布 v1.1 2018-03-12 增加新技術(shù)知識(shí)、完善知識(shí)體系 v2.0 2019-02-19 結(jié)構(gòu)...

    Olivia 評(píng)論0 收藏0
  • Java 運(yùn)行時(shí)獲取方法參數(shù)名

    摘要:原文如果覺(jué)得我的文章對(duì)你有用,請(qǐng)隨意贊賞本文整理運(yùn)行時(shí)獲取方法參數(shù)名的兩種方法,的最新的方法和之前的方法。文件中的調(diào)試信息上文介紹了通過(guò)新增的反射運(yùn)行時(shí)獲取方法參數(shù)名。 原文:http://nullwy.me/2017/04/java...如果覺(jué)得我的文章對(duì)你有用,請(qǐng)隨意贊賞 本文整理 Java 運(yùn)行時(shí)獲取方法參數(shù)名的兩種方法,Java 8 的最新的方法和 Java 8 之前的方法。 ...

    cfanr 評(píng)論0 收藏0
  • 你和阿里資深架構(gòu)師之間,差不僅僅是年齡(進(jìn)階必看)

    摘要:導(dǎo)讀閱讀本文需要有足夠的時(shí)間,筆者會(huì)由淺到深帶你一步一步了解一個(gè)資深架構(gòu)師所要掌握的各類知識(shí)點(diǎn),你也可以按照文章中所列的知識(shí)體系對(duì)比自身,對(duì)自己進(jìn)行查漏補(bǔ)缺,覺(jué)得本文對(duì)你有幫助的話,可以點(diǎn)贊關(guān)注一下。目錄一基礎(chǔ)篇二進(jìn)階篇三高級(jí)篇四架構(gòu)篇五擴(kuò) 導(dǎo)讀:閱讀本文需要有足夠的時(shí)間,筆者會(huì)由淺到深帶你一步一步了解一個(gè)資深架構(gòu)師所要掌握的各類知識(shí)點(diǎn),你也可以按照文章中所列的知識(shí)體系對(duì)比自身,對(duì)自己...

    huaixiaoz 評(píng)論0 收藏0
  • 一個(gè)簡(jiǎn)單例子教會(huì)您使用javap

    摘要:從字節(jié)碼的分析可以觀察到一個(gè)有趣的現(xiàn)象,再次看看我們的語(yǔ)句。這張表里每行的后面的數(shù)字代表源代碼的序號(hào),冒號(hào)后面的數(shù)字代表字節(jié)碼里每行指令的序號(hào)。維護(hù)了源代碼同字節(jié)指令的映射關(guān)系,確保了代碼調(diào)試的順利進(jìn)行。 javap是JDK自帶的工具: showImg(https://segmentfault.com/img/remote/1460000016730237); 這篇文章使用下面這段簡(jiǎn)單...

    BLUE 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<