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;
}
-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;
}
相关文章推荐
- Delphi中String类型原理介绍
- java编译器原理 javac
- String创建的原理
- String的hashCode原理
- String 一旦被赋值,就不能改变 原理
- JAVA switch 支持string 表达式的原理
- java byte与char、String互转原理
- OutputDebugString的原理及模拟源码
- Delphi 中String类型原理介绍
- javac 编译器原理
- 《coredump问题原理探究》windows版7.6节string
- [FAQ]String(字串相連)與StringBuilder的差別、原理與優缺點?
- 深入分析java web javac编译原理(其一)
- java中的String类型的存储原理和一些细节
- String事务原理
- String StringBuffer StringBuilder原理
- Delphi中String类型原理介绍
- String的原理与用法总结
- Javac编译原理
- Java中字符串String Switch的实现原理