String+String的javac原理和javap

javap是jdk自带的一个工具,可以反编译,也可以查看java编译器生成的字节码,是分析代码的一个好工具。

-help 帮助
-l 输出行和 变量的表
-public 只输出public方法和域
-protected 只输出public和protected类和成员
-package 只输出包,public和protected类和成员,这是默认的
-p -private 输出所有类和成员
-s 输出内部类型签名
-c 输出分解后的代码,例如,类中每一个方法内,包含java 字节码的指令,
-verbose 输出栈大小,方法参数的个数
-constants 输出静态final常量


Java代码  
  1. package test;  
  2.   
  3. public class Test {  
  4.   
  5.     public static void main(String[] args) {  
  6.   
  7.         String s1 = new String("小菜鸟");  
  8.         String s2 = new String("大菜鸟");  
  9.           
  10.         String resultString = s1 + s2 + "老鸟";  
  11.     }  
  12.   
  13. }  


以上代码编译成class文件后 
用javap Test -verbose 命令看下字节码文件中的内容: 
注意下面代码第100行,重点所在  
Java代码   收藏代码
  1. D:\Workspace\MyEclipse\workspace\Test\bin\test>javap Test -verbose  
  2. Compiled from "Test.java"  
  3. public class test.Test extends java.lang.Object  
  4.   SourceFile: "Test.java"  
  5.   minor version: 0  
  6.   major version: 50  
  7.   Constant pool:  
  8. const #1 = class        #2;     //  test/Test  
  9. const #2 = Asciz        test/Test;  
  10. const #3 = class        #4;     //  java/lang/Object  
  11. const #4 = Asciz        java/lang/Object;  
  12. const #5 = Asciz        <init>;  
  13. const #6 = Asciz        ()V;  
  14. const #7 = Asciz        Code;  
  15. const #8 = Method       #3.#9;  //  java/lang/Object."<init>":()V  
  16. const #9 = NameAndType  #5:#6;//  "<init>":()V  
  17. const #10 = Asciz       LineNumberTable;  
  18. const #11 = Asciz       LocalVariableTable;  
  19. const #12 = Asciz       this;  
  20. const #13 = Asciz       Ltest/Test;;  
  21. const #14 = Asciz       main;  
  22. const #15 = Asciz       ([Ljava/lang/String;)V;  
  23. const #16 = class       #17;    //  java/lang/String  
  24. const #17 = Asciz       java/lang/String;  
  25. const #18 = String      #19;    //  小菜鸟  
  26. const #19 = Asciz       小菜鸟;  
  27. const #20 = Method      #16.#21;        //  java/lang/String."<init>":(Ljava/lan  
  28. g/String;)V  
  29. const #21 = NameAndType #5:#22;//  "<init>":(Ljava/lang/String;)V  
  30. const #22 = Asciz       (Ljava/lang/String;)V;  
  31. const #23 = String      #24;    //  大菜鸟  
  32. const #24 = Asciz       大菜鸟;  
  33. const #25 = class       #26;    //  java/lang/StringBuilder  
  34. const #26 = Asciz       java/lang/StringBuilder;  
  35. const #27 = Method      #16.#28;        //  java/lang/String.valueOf:(Ljava/lang  
  36. /Object;)Ljava/lang/String;  
  37. const #28 = NameAndType #29:#30;//  valueOf:(Ljava/lang/Object;)Ljava/lang/Strin  
  38. g;  
  39. const #29 = Asciz       valueOf;  
  40. const #30 = Asciz       (Ljava/lang/Object;)Ljava/lang/String;;  
  41. const #31 = Method      #25.#21;        //  java/lang/StringBuilder."<init>":(Lj  
  42. ava/lang/String;)V  
  43. const #32 = Method      #25.#33;        //  java/lang/StringBuilder.append:(Ljav  
  44. a/lang/String;)Ljava/lang/StringBuilder;  
  45. const #33 = NameAndType #34:#35;//  append:(Ljava/lang/String;)Ljava/lang/String  
  46. Builder;  
  47. const #34 = Asciz       append;  
  48. const #35 = Asciz       (Ljava/lang/String;)Ljava/lang/StringBuilder;;  
  49. const #36 = String      #37;    //  老鸟  
  50. const #37 = Asciz       老鸟;  
  51. const #38 = Method      #25.#39;        //  java/lang/StringBuilder.toString:()L  
  52. java/lang/String;  
  53. const #39 = NameAndType #40:#41;//  toString:()Ljava/lang/String;  
  54. const #40 = Asciz       toString;  
  55. const #41 = Asciz       ()Ljava/lang/String;;  
  56. const #42 = Asciz       args;  
  57. const #43 = Asciz       [Ljava/lang/String;;  
  58. const #44 = Asciz       s1;  
  59. const #45 = Asciz       Ljava/lang/String;;  
  60. const #46 = Asciz       s2;  
  61. const #47 = Asciz       resultString;  
  62. const #48 = Asciz       SourceFile;  
  63. const #49 = Asciz       Test.java;  
  64.   
  65. {  
  66. public test.Test();  
  67.   Code:  
  68.    Stack=1, Locals=1, Args_size=1  
  69.    0:   aload_0  
  70.    1:   invokespecial   #8//Method java/lang/Object."<init>":()V  
  71.    4:   return  
  72.   LineNumberTable:  
  73.    line 30  
  74.   
  75.   LocalVariableTable:  
  76.    Start  Length  Slot  Name   Signature  
  77.    0      5      0    this       Ltest/Test;  
  78.   
  79.   
  80. public static void main(java.lang.String[]);  
  81.   Code:  
  82.    Stack=3, Locals=4, Args_size=1  
  83.    0:   new     #16//class java/lang/String |我加上的:创建一个新对象,对象类型存储在常量池#16  
  84.    3:   dup             //我加上的:复制栈顶部一个字长的内容  
  85.    4:   ldc     #18//String 小菜鸟 |我加上的:把常量池中索引为#18的值压入栈  
  86.    6:   invokespecial   #20//Method java/lang/String."<init>":(Ljava/lang/String;)V |我加上的:调用初始化方法  
  87.    9:   astore_1        //我加上的:将引用类型存入局部变量1  
  88.    10:  new     #16//class java/lang/String |我加上的:10-19同上实例化另一个String对象(大菜鸟)  
  89.    13:  dup  
  90.    14:  ldc     #23//String 大菜鸟  
  91.    16:  invokespecial   #20//Method java/lang/String."<init>":(Ljava/lang/String;)V  
  92.    19:  astore_2  
  93.    20:  new     #25//class java/lang/StringBuilder |我加上的:创建一个StringBuilder对象  
  94.    23:  dup  
  95.    24:  aload_1         //我加上的:从局部变量1中装载引用类型  
  96.    25:  invokestatic    #27//Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;  
  97.    28:  invokespecial   #31//Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V  
  98.    31:  aload_2         //我加上的:从局部变量2中装载引用类型  
  99.    //哈哈,看到这里了吧,javac(我的jdk版本是1.6)编译后的字节码对于String+String+...的处理也是使用StringBuilder的append的  
  100.    32:  invokevirtual   #32//Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;  
  101.    35:  ldc     #36//String 老鸟  
  102.    //同理,连接字符串“老鸟”  
  103.    37:  invokevirtual   #32//Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;  
  104.    40:  invokevirtual   #38//Method java/lang/StringBuilder.toString:()Ljava/lang/String;  
  105.    43:  astore_3  
  106.    44:  return  
  107.   LineNumberTable:  
  108.    line 70  
  109.    line 810  
  110.    line 1020  
  111.    line 1144  
  112.   
  113.   LocalVariableTable:  
  114.    Start  Length  Slot  Name   Signature  
  115.    0      45      0    args       [Ljava/lang/String;  
  116.    10      35      1    s1       Ljava/lang/String;  
  117.    20      25      2    s2       Ljava/lang/String;  
  118.    44      1      3    resultString       Ljava/lang/String;  
  119.   
  120.   
  121. }  
  122.   

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值