":()V
& X+ }8 d) G* w1 |; U- h 4: return
0 @* O% Y; D, H LineNumberTable:4 L2 ~ G* F) L; K$ e# r
line 2: 09 S' O3 Z/ s5 k z& i
LocalVariableTable:) l) X! c5 o+ R* ? }
Start Length Slot Name Signature
% e; Z! c8 Y( { ^: W/ ^6 ^ 0 5 0 this LDemo;</p>public void sayHello3();. T6 A, Q0 O# s) [* r
Code:' p# [) n, | m1 ?
Stack=2, Locals=1, Args_size=1
0 G7 s% ^1 q1 S) g) U5 n5 a8 j 0: getstatic #25; //Field java/lang/System.out:Ljava/io/PrintStream;
# v2 i( n2 y; g9 M% J 3: ldc #43; //String this is method3...
8 x( g' @) u [7 @# o$ y" h8 e 5: invokevirtual #33; //Method java/io/PrintStream.println:(Ljava/lang/String;)V, N# I( o& r. K: K) \
8: return
" H4 Y2 d4 l) `7 w4 w% A LineNumberTable:* [ E9 t0 G& x: ?
line 17: 03 d. n3 \ S1 H! u
line 18: 8
$ E( ^/ X8 N. B# H4 O LocalVariableTable:$ N% w1 K/ C/ g0 v( R# t R
Start Length Slot Name Signature7 p8 m: u; e3 I' u6 Q9 t z. ~
0 9 0 this LDemo;
4 V) s5 W$ C+ f4 Z}
5 q) h0 U% @, R3 s9 u解析:% s+ |" I/ u: v( ^: `' f# V
1、版本号 major version: 49 //java版本 jdk1.6显示的是50, jdk1.5显示的是49,jdk1.4显示的是58 , 高版本能执行低版本的class文件' t- F' C1 K! q9 @- B
2、常量池Constant pool
7 C+ i' h' `+ l; H8 c Method:方法' ]0 a8 N# ^/ D6 i* F0 t0 z# T7 h" P
Field:字段
4 F) A. ?6 |9 @ String:字符串% |: G, ]% P9 g M' d1 B
Asciz:签名如由jvm调用,其他是不能够去调用它的2 C; I. s9 D) ]9 a3 z0 M/ ~' c
NameAndType:变量名的类型
. B; u0 @+ i# X Class:类
8 }' M! X y0 q 通过字节码,我们可以看到Demo类 继承于java.lang.Object,如果类中没有显式声明构造函数的话,编译器会插入一个缺省无参的构造函数(构造函数在JVM级别是显示成的普通函数)。
/ E4 Z" _- K* C0 p 三:检测代码的效率问题$ ^ E* Y# O5 }6 k$ V- h
学习Java的过程中,都会了解到字符串合并时要用到StringBuffer 来代替String,那下面就来通过Java字节码来验证两种方式的效率性。
# ]8 ^+ R/ `! I9 ?$ Q; ] 例子:一个Java类 TestString.java4 I' X! |' i" K7 ~3 v
public class TestString {
# c+ l z' X( r: ~4 s4 \ public String testString(String str1, String str2){
l1 z" |" B& b3 X( c8 l7 \ return str1 + str2;8 h2 o. o( [6 Z4 _
}
1 Y( Z+ {) }8 p# J) C: Z public String testStringBuffer(StringBuffer sb, String str){
, B$ z n, I8 g7 J% y return sb.append(str).toString();' j p6 S% W% _: c' i1 F% h* h
}5 ?8 ~- T6 N( `
}: x ^5 o- H7 |0 A0 k
8 q* }$ L) s3 E% s
javap –c TestString 后字节码信息:- K; H1 B k8 @0 y Y. G7 x2 x6 B$ Y
Compiled from "TestString.java"
?# k" Z6 m& d# C+ z( e; epublic class TestString extends java.lang.Object{
% D) M) T) N4 K- @public TestString();' z0 ?8 f% a7 T
Code:
; P. s' M% x2 z, n 0: aload_0
6 K2 R9 L0 N( f+ C6 O 1: invokespecial #8; //Method java/lang/Object."":()V
2 f, \% V' { P; T; `9 v7 j 4: return' L/ o4 m6 W/ v' J- f9 g K b
public java.lang.String testString(java.lang.String, java.lang.String);
- h+ ~1 T. O( N2 G ~6 L Code:) z! }! K# ?0 W! P6 Q, _* I' s
0: new #16; //class java/lang/StringBuilder* N3 _9 m% u, ?/ P# f
3: dup$ ]* S- O5 K% D' C9 s9 @' L( C
4: aload_1 _5 i3 Z5 P, p H0 q
5: invokestatic #18; //Method java/lang/String.valueOf:(Ljava/lang/Object;)Ljava/lang/String;
/ H% h) u+ @, q3 p 8: invokespecial #24; //Method java/lang/StringBuilder."":(Ljava/lang/String;)V
. U1 | S. H7 e. ~8 a5 H8 D- { 11: aload_2
% _& g+ T7 b3 U* u+ J 12: invokevirtual #27; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
* I; v5 {" F: n9 u 15: invokevirtual #31; //Method java/lang/StringBuilder.toString:()Ljava/lang/String;
# c8 l& [7 C) f e 18: areturn
5 B( z. e1 }/ i0 n
% u" y, M+ X! d: R9 `+ N7 g- X) opublic java.lang.String testStringBuffer(java.lang.StringBuffer, java.lang.String); c/ G9 p( ~4 r1 B, x9 `
Code:
! k: H! ]9 {$ }+ _, Q" r+ f6 @2 Y# I 0: aload_1
1 W# G+ }+ X4 H7 B: f9 j, B 1: aload_22 N6 J# M; k% d
2: invokevirtual #40; //Method java/lang/StringBuffer.append:(Ljava/lang/String;)Ljava/lang/StringBuffer;
6 j( T0 h! u0 u3 y 5: invokevirtual #45; //Method java/lang/StringBuffer.toString:()Ljava/lang/String;* `" g+ g x: x4 `
8: areturnwww.ExamW.CoM# H0 R8 a4 Q! Q q0 O" f% M# X
} |