您的位置:首页 > 编程语言 > Java开发

String+String的javac原理和javap

2014-11-27 09:37 85 查看
javap是jdk自带的一个工具,可以反编译,也可以查看java编译器生成的字节码,是分析代码的一个好工具。

-help 帮助

-l 输出行和变量的表

-public 只输出public方法和域

-protected 只输出public和protected类和成员

-package 只输出包,public和protected类和成员,这是默认的

-p -private 输出所有类和成员

-s 输出内部类型签名

-c 输出分解后的代码,例如,类中每一个方法内,包含java字节码的指令,

-verbose 输出栈大小,方法参数的个数

-constants 输出静态final常量

Java代码  

package test;  

  

public class Test {  

  

    public static void main(String[] args) {  

  

        String s1 = new String("小菜鸟");  

        String s2 = new String("大菜鸟");  

          

        String resultString = s1 + s2 + "老鸟";  

    }  

  

}  

以上代码编译成class文件后 
用javap Test -verbose 命令看下字节码文件中的内容: 
注意下面代码第100行,重点所在 

Java代码  


D:\Workspace\MyEclipse\workspace\Test\bin\test>javap Test -verbose  

Compiled from "Test.java"  

public class test.Test extends java.lang.Object  

  SourceFile: "Test.java"  

  minor version: 0  

  major version: 50  

  Constant pool:  

const #1 = class        #2;     //  test/Test  

const #2 = Asciz        test/Test;  

const #3 = class        #4;     //  java/lang/Object  

const #4 = Asciz        java/lang/Object;  

const #5 = Asciz        <init>;  

const #6 = Asciz        ()V;  

const #7 = Asciz        Code;  

const #8 = Method       #3.#9;  //  java/lang/Object."<init>":()V  

const #9 = NameAndType  #5:#6;//  "<init>":()V  

const #10 = Asciz       LineNumberTable;  

const #11 = Asciz       LocalVariableTable;  

const #12 = Asciz       this;  

const #13 = Asciz       Ltest/Test;;  

const #14 = Asciz       main;  

const #15 = Asciz       ([Ljava/lang/String;)V;  

const #16 = class       #17;    //  java/lang/String  

const #17 = Asciz       java/lang/String;  

const #18 = String      #19;    //  小菜鸟  

const #19 = Asciz       小菜鸟;  

const #20 = Method      #16.#21;        //  java/lang/String."<init>":(Ljava/lan  

g/String;)V  

const #21 = NameAndType #5:#22;//  "<init>":(Ljava/lang/String;)V  

const #22 = Asciz       (Ljava/lang/String;)V;  

const #23 = String      #24;    //  大菜鸟  

const #24 = Asciz       大菜鸟;  

const #25 = class       #26;    //  java/lang/StringBuilder  

const #26 = Asciz       java/lang/StringBuilder;  

const #27 = Method      #16.#28;        //  java/lang/String.valueOf:(Ljava/lang  

/Object;)Ljava/lang/String;  

const #28 = NameAndType #29:#30;//  valueOf:(Ljava/lang/Object;)Ljava/lang/Strin  

g;  

const #29 = Asciz       valueOf;  

const #30 = Asciz       (Ljava/lang/Object;)Ljava/lang/String;;  

const #31 = Method      #25.#21;        //  java/lang/StringBuilder."<init>":(Lj  

ava/lang/String;)V  

const #32 = Method      #25.#33;        //  java/lang/StringBuilder.append:(Ljav  

a/lang/String;)Ljava/lang/StringBuilder;  

const #33 = NameAndType #34:#35;//  append:(Ljava/lang/String;)Ljava/lang/String  

Builder;  

const #34 = Asciz       append;  

const #35 = Asciz       (Ljava/lang/String;)Ljava/lang/StringBuilder;;  

const #36 = String      #37;    //  老鸟  

const #37 = Asciz       老鸟;  

const #38 = Method      #25.#39;        //  java/lang/StringBuilder.toString:()L  

java/lang/String;  

const #39 = NameAndType #40:#41;//  toString:()Ljava/lang/String;  

const #40 = Asciz       toString;  

const #41 = Asciz       ()Ljava/lang/String;;  

const #42 = Asciz       args;  

const #43 = Asciz       [Ljava/lang/String;;  

const #44 = Asciz       s1;  

const #45 = Asciz       Ljava/lang/String;;  

const #46 = Asciz       s2;  

const #47 = Asciz       resultString;  

const #48 = Asciz       SourceFile;  

const #49 = Asciz       Test.java;  

  

{  

public test.Test();  

  Code:  

   Stack=1, Locals=1, Args_size=1  

   0:   aload_0  

   1:   invokespecial   #8; //Method java/lang/Object."<init>":()V  

   4:   return  

  LineNumberTable:  

   line 3: 0  

  

  LocalVariableTable:  

   Start  Length  Slot  Name   Signature  

   0      5      0    this       Ltest/Test;  

  

  

public static void main(java.lang.String[]);  

  Code:  

   Stack=3, Locals=4, Args_size=1  

   0:   new     #16; //class java/lang/String |我加上的:创建一个新对象,对象类型存储在常量池#16  

   3:   dup             //我加上的:复制栈顶部一个字长的内容  

   4:   ldc     #18; //String 小菜鸟 |我加上的:把常量池中索引为#18的值压入栈  

   6:   invokespecial   #20; //Method java/lang/String."<init>":(Ljava/lang/String;)V |我加上的:调用初始化方法  

   9:   astore_1        //我加上的:将引用类型存入局部变量1  

   10:  new     #16; //class java/lang/String |我加上的:10-19同上实例化另一个String对象(大菜鸟)  

   13:  dup  

   14:  ldc     #23; //String 大菜鸟  

   16:  invokespecial   #20; //Method java/lang/String."<init>":(Ljava/lang/String;)V  

   19:  astore_2  

   20:  new     #25; //class java/lang/StringBuilder |我加上的:创建一个StringBuilder对象  

   23:  dup  

   24:  aload_1         //我加上的:从局部变量1中装载引用类型  

   25:  invokestatic    #27; //Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;  

   28:  invokespecial   #31; //Method java/lang/StringBuilder."<init>":(Ljava/lang/String;)V  

   31:  aload_2         //我加上的:从局部变量2中装载引用类型  

   //哈哈,看到这里了吧,javac(我的jdk版本是1.6)编译后的字节码对于String+String+...的处理也是使用StringBuilder的append的  

   32:  invokevirtual   #32; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;  

   35:  ldc     #36; //String 老鸟  

   //同理,连接字符串“老鸟”  

   37:  invokevirtual   #32; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;  

   40:  invokevirtual   #38; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;  

   43:  astore_3  

   44:  return  

  LineNumberTable:  

   line 7: 0  

   line 8: 10  

   line 10: 20  

   line 11: 44  

  

  LocalVariableTable:  

   Start  Length  Slot  Name   Signature  

   0      45      0    args       [Ljava/lang/String;  

   10      35      1    s1       Ljava/lang/String;  

   20      25      2    s2       Ljava/lang/String;  

   44      1      3    resultString       Ljava/lang/String;  

  

  

}  

  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: