【转】用 BCEL 设计字节码
查到一篇使用BCEL了,
Java 编程的动态性,第 7 部分: 用 BCEL 设计字节码,网址是 http://www-128.ibm.com/developerworks/cn/java/j-dyn0414/
字节码处理的工具也挺多,什么时候再看看asm
import
java.io.FileOutputStream;
import org.apache.bcel.Constants;
import org.apache.bcel.classfile.ClassParser;
import org.apache.bcel.classfile.JavaClass;
import org.apache.bcel.classfile.Method;
import org.apache.bcel.generic.ClassGen;
import org.apache.bcel.generic.ConstantPoolGen;
import org.apache.bcel.generic.GETSTATIC;
import org.apache.bcel.generic.INVOKEVIRTUAL;
import org.apache.bcel.generic.InstructionConstants;
import org.apache.bcel.generic.InstructionFactory;
import org.apache.bcel.generic.InstructionList;
import org.apache.bcel.generic.MethodGen;
import org.apache.bcel.generic.ObjectType;
import org.apache.bcel.generic.PUSH;
import org.apache.bcel.generic.Type;
public class BCELTiming {
private static void addWrapper(ClassGen cgen,Method method){
//set up the construction tools
InstructionFactory ifact = new InstructionFactory(cgen);
InstructionList ilist = new InstructionList();
ConstantPoolGen pgen = cgen.getConstantPool();
String cname = cgen.getClassName();
MethodGen wrapgen = new MethodGen(method,cname,pgen);
wrapgen.setInstructionList(ilist);
//rename a copy of the original method
MethodGen methgen = new MethodGen(method,cname,pgen);
cgen.removeMethod(method);
String iname = methgen.getName()+"$impl";
methgen.setName(iname);
cgen.addMethod(methgen.getMethod());
Type returnType = methgen.getReturnType();
// methgen.addLocalVariable(name, type, slot, start, end)
Type[] types = methgen.getArgumentTypes();
int slot = methgen.isStatic()?0:1;//非静态方法slot 0处应该存储的是this
//// 这种方式与Java如何处理方法调用有关。对于非静态的方法,每次调用的第一个(隐藏的)参数是目标对象的this引用(就是位置0储存的内容)。
for(int i = 0;i<types.length;i++){
slot += types[i].getSize();//long,double的size为2
}
//save time prior to invocation
//createInvoke在常量池增加了 addMethodref,并且addMethodref方法会先在常量池中查找是否有这个方法存在,没有则创建一系列的与此方法相关的常量池内容
//看看这个方法是怎么实现的,为什么此方法中INVOKEINTERFACE的要有nargs
//InstructionFactory的实例方法一般要用到cp在常量池中添加引用,其静态的方法一般只是创建一些指令,而这些指令不需要在常量池添加内容
//INVOKEXXXXX指令包括一个index指示此方法在常量池中的索引
//// 调用静态的long java.lang.System.currentTimeMillis()方法,调用结束后函数的返回的long类型的值会压入operand stack操作数堆栈
ilist.append(ifact.createInvoke("java.lang.System", "currentTimeMillis",
Type.LONG, Type.NO_ARGS, Constants.INVOKESTATIC));//currentTimemillis()的方法结果在operand stack栈顶
//createStore方法生成了XSTORE指令,弹出operand stack栈顶的元素写入到某个局部变量中,
//参照之前打印出的局部变量的信息可以知道若是实例方法则 index=0处保留的this,之后是用到的方法参数的index,然后是方法内定义的局部变量
//slot标记在局部变量中的位置,
//这个局部变量没有设置名称????????
ilist.append(InstructionFactory.createStore(Type.LONG, slot));
//call the wrapped method
int offset =0;
short invoke = Constants.INVOKESTATIC;
//如果是实例方法则load this到栈中
if(!methgen.isStatic()){
//// 如果不是调用静态函数,将调用的第一个(隐藏的)参数(目标对象的this引用)压入operand stack
ilist.append(InstructionFactory.createLoad(Type.OBJECT, 0));
offset =1;
invoke = Constants.INVOKESPECIAL;
}
//load 参数到栈中
for(int i=0;i<types.length;i++){
Type type = types[i];
ilist.append(InstructionFactory.createLoad(type, offset));// 按参数类型把参数一个个从本地变量堆栈取出,压入operand stack
//Long Double的size为2,void为0,其他的为1
offset += type.getSize();
}
//执行方法buildString$impl()
ilist.append(ifact.createInvoke(cname, iname,
returnType, types, invoke));//消耗oprand stack的this参数和length参数
//并将结果保存在操作数的栈顶
//stor result for return later
if(returnType != Type.VOID){
//+2是因为之前加的的long局部变量占两个2个字,这个字是虚拟机定义的,一般为32位
//// 将名为iname的函数返回值复制到本地变量堆栈的slot+2的位置上
ilist.append(InstructionFactory.createStore(returnType,slot+2));
}
//print time required for method call
//createFieldAccess中的 addFieldref方法先在ConstantFieldref常量池中根据type的描述符创建引用
//然后根据kind来创建是GETFIELD,PUTFIELD,GETSTATIC,PUTSTATIC哪个指令
//// 获取静态对象java.lang.System.out的引用,返回值压入operand stack
ilist.append(ifact.createFieldAccess("java.lang.System"
, "out", new ObjectType("java.io.PrintStream"),
Constants.GETSTATIC));//out会在栈顶
//ilist.append(InstructionFactory.createDup(1));
ilist.append(InstructionConstants.DUP);//复制栈顶元素out
ilist.append(InstructionConstants.DUP);//在复制,当前栈顶前三元素都为out引用,供下面的三次print使用out引用
String text = "Call to method "+methgen.getName()+" took ";
//实际还是调的new LDC
ilist.append(new PUSH(pgen,text));
ilist.append(ifact.createInvoke("java.io.PrintStream",
"print", Type.VOID, new Type[]{Type.STRING},
Constants.INVOKEVIRTUAL));//消耗调一个out和栈顶的一个元素
// 调用结束,operand stack弹出一个String的引用和一个out的引用(还剩2个out),函数没有返回值
ilist.append(ifact.createInvoke("java.lang.System",
"currentTimeMillis", Type.LONG, Type.NO_ARGS,
Constants.INVOKESTATIC));//operand stack栈顶保留此方法的结果,即结束时间
//调用java.lang.System.currentTimeMillis()方法,调用结束后函数的返回的long类型的值会压入堆栈operand
//load 局部变量到栈顶
//从本地变量堆栈的slot位置载入先前储存的long值,压入operand stack
ilist.append(InstructionFactory.createLoad(Type.LONG, slot));
//栈顶两个元素进行减法操作,结果保存在栈顶
// 调用long的减法指令,弹出2个long值,并把结果压入operand stack,现在operand stack的top第一个是long,第二个是out的引用
ilist.append(InstructionConstants.LSUB);
ilist.append(ifact.createInvoke("java.io.PrintStream",
"print", Type.VOID, new Type[]{Type.LONG},
Constants.INVOKEVIRTUAL));//消耗一个out,和减法的结果
// 将String对象" ms."放入pgen,并把其在pgen的引用(这个引用其实是字符串在常量池中的索引下标)压入operand stack(供out.print(Sting)调用的参数)
ilist.append(new PUSH(pgen," ms."));//常量入栈,首先会判断常量池中是否有此字符串
ilist.append(ifact.createInvoke("java.io.PrintStream",
"println", Type.VOID, new Type[]{Type.STRING},
Constants.INVOKEVIRTUAL));//消耗调最后一个out和刚入栈的" ms."
//如果返回类型不为void,则将返回结果入栈并返回
if(returnType != Type.VOID){
//处理返回值,如果不为空,从本地局部对象堆栈的slot+2位置读取指定类型的返回值压入operand stack
ilist.append(InstructionFactory.createLoad(returnType, slot+2));
}
ilist.append(InstructionFactory.createReturn(returnType));//根据相应的返回类型创建相应的返回指令
//finalize the construted method
wrapgen.stripAttributes(true);
wrapgen.setMaxStack();
wrapgen.setMaxLocals();
cgen.addMethod(wrapgen.getMethod());
ilist.dispose();
/**//*
* ifact.createPrintln(s)
*
* public InstructionList createPrintln( String s ) {
InstructionList il = new InstructionList();
int out = cp.addFieldref("java.lang.System", "out", "Ljava/io/PrintStream;");
int println = cp.addMethodref("java.io.PrintStream", "println", "(Ljava/lang/String;)V");
il.append(new GETSTATIC(out));
il.append(new PUSH(cp, s));
il.append(new INVOKEVIRTUAL(println));
return il;
}
*/
}
/** *//**
* @param args
*/
public static void main(String[] args) {
args[0]="D:\\java to eclipse\\javaeclipsestudy\\workspace\\BCELTest\\bin\\StringBuilder.class";
args[1]="buildString";
String targetClassfile = "StringBuilder.class";
if(args.length==2 && args[0].endsWith(".class")){
try{
JavaClass jclas = new ClassParser(args[0]).parse();
ClassGen cgen = new ClassGen(jclas);
Method[] methods = jclas.getMethods();
int index;
for(index =0;index<methods.length;index++){
if(methods[index].getName().equals(args[1])){
break;
}
}
if(index<methods.length){
addWrapper(cgen,methods[index]);
FileOutputStream fos = new FileOutputStream(targetClassfile);
cgen.getJavaClass().dump(fos);
fos.close();
}else{
System.err.println("Method " + args[1]+"not found in"+ args[0]);
}
}catch(Exception e){
e.printStackTrace();
}
}else{
System.out.println("usage: class-file method-name");
}
}
}
import org.apache.bcel.Constants;
import org.apache.bcel.classfile.ClassParser;
import org.apache.bcel.classfile.JavaClass;
import org.apache.bcel.classfile.Method;
import org.apache.bcel.generic.ClassGen;
import org.apache.bcel.generic.ConstantPoolGen;
import org.apache.bcel.generic.GETSTATIC;
import org.apache.bcel.generic.INVOKEVIRTUAL;
import org.apache.bcel.generic.InstructionConstants;
import org.apache.bcel.generic.InstructionFactory;
import org.apache.bcel.generic.InstructionList;
import org.apache.bcel.generic.MethodGen;
import org.apache.bcel.generic.ObjectType;
import org.apache.bcel.generic.PUSH;
import org.apache.bcel.generic.Type;
public class BCELTiming {
private static void addWrapper(ClassGen cgen,Method method){
//set up the construction tools
InstructionFactory ifact = new InstructionFactory(cgen);
InstructionList ilist = new InstructionList();
ConstantPoolGen pgen = cgen.getConstantPool();
String cname = cgen.getClassName();
MethodGen wrapgen = new MethodGen(method,cname,pgen);
wrapgen.setInstructionList(ilist);
//rename a copy of the original method
MethodGen methgen = new MethodGen(method,cname,pgen);
cgen.removeMethod(method);
String iname = methgen.getName()+"$impl";
methgen.setName(iname);
cgen.addMethod(methgen.getMethod());
Type returnType = methgen.getReturnType();
// methgen.addLocalVariable(name, type, slot, start, end)
Type[] types = methgen.getArgumentTypes();
int slot = methgen.isStatic()?0:1;//非静态方法slot 0处应该存储的是this
//// 这种方式与Java如何处理方法调用有关。对于非静态的方法,每次调用的第一个(隐藏的)参数是目标对象的this引用(就是位置0储存的内容)。
for(int i = 0;i<types.length;i++){
slot += types[i].getSize();//long,double的size为2
}
//save time prior to invocation
//createInvoke在常量池增加了 addMethodref,并且addMethodref方法会先在常量池中查找是否有这个方法存在,没有则创建一系列的与此方法相关的常量池内容
//看看这个方法是怎么实现的,为什么此方法中INVOKEINTERFACE的要有nargs
//InstructionFactory的实例方法一般要用到cp在常量池中添加引用,其静态的方法一般只是创建一些指令,而这些指令不需要在常量池添加内容
//INVOKEXXXXX指令包括一个index指示此方法在常量池中的索引
//// 调用静态的long java.lang.System.currentTimeMillis()方法,调用结束后函数的返回的long类型的值会压入operand stack操作数堆栈
ilist.append(ifact.createInvoke("java.lang.System", "currentTimeMillis",
Type.LONG, Type.NO_ARGS, Constants.INVOKESTATIC));//currentTimemillis()的方法结果在operand stack栈顶
//createStore方法生成了XSTORE指令,弹出operand stack栈顶的元素写入到某个局部变量中,
//参照之前打印出的局部变量的信息可以知道若是实例方法则 index=0处保留的this,之后是用到的方法参数的index,然后是方法内定义的局部变量
//slot标记在局部变量中的位置,
//这个局部变量没有设置名称????????
ilist.append(InstructionFactory.createStore(Type.LONG, slot));
//call the wrapped method
int offset =0;
short invoke = Constants.INVOKESTATIC;
//如果是实例方法则load this到栈中
if(!methgen.isStatic()){
//// 如果不是调用静态函数,将调用的第一个(隐藏的)参数(目标对象的this引用)压入operand stack
ilist.append(InstructionFactory.createLoad(Type.OBJECT, 0));
offset =1;
invoke = Constants.INVOKESPECIAL;
}
//load 参数到栈中
for(int i=0;i<types.length;i++){
Type type = types[i];
ilist.append(InstructionFactory.createLoad(type, offset));// 按参数类型把参数一个个从本地变量堆栈取出,压入operand stack
//Long Double的size为2,void为0,其他的为1
offset += type.getSize();
}
//执行方法buildString$impl()
ilist.append(ifact.createInvoke(cname, iname,
returnType, types, invoke));//消耗oprand stack的this参数和length参数
//并将结果保存在操作数的栈顶
//stor result for return later
if(returnType != Type.VOID){
//+2是因为之前加的的long局部变量占两个2个字,这个字是虚拟机定义的,一般为32位
//// 将名为iname的函数返回值复制到本地变量堆栈的slot+2的位置上
ilist.append(InstructionFactory.createStore(returnType,slot+2));
}
//print time required for method call
//createFieldAccess中的 addFieldref方法先在ConstantFieldref常量池中根据type的描述符创建引用
//然后根据kind来创建是GETFIELD,PUTFIELD,GETSTATIC,PUTSTATIC哪个指令
//// 获取静态对象java.lang.System.out的引用,返回值压入operand stack
ilist.append(ifact.createFieldAccess("java.lang.System"
, "out", new ObjectType("java.io.PrintStream"),
Constants.GETSTATIC));//out会在栈顶
//ilist.append(InstructionFactory.createDup(1));
ilist.append(InstructionConstants.DUP);//复制栈顶元素out
ilist.append(InstructionConstants.DUP);//在复制,当前栈顶前三元素都为out引用,供下面的三次print使用out引用
String text = "Call to method "+methgen.getName()+" took ";
//实际还是调的new LDC
ilist.append(new PUSH(pgen,text));
ilist.append(ifact.createInvoke("java.io.PrintStream",
"print", Type.VOID, new Type[]{Type.STRING},
Constants.INVOKEVIRTUAL));//消耗调一个out和栈顶的一个元素
// 调用结束,operand stack弹出一个String的引用和一个out的引用(还剩2个out),函数没有返回值
ilist.append(ifact.createInvoke("java.lang.System",
"currentTimeMillis", Type.LONG, Type.NO_ARGS,
Constants.INVOKESTATIC));//operand stack栈顶保留此方法的结果,即结束时间
//调用java.lang.System.currentTimeMillis()方法,调用结束后函数的返回的long类型的值会压入堆栈operand
//load 局部变量到栈顶
//从本地变量堆栈的slot位置载入先前储存的long值,压入operand stack
ilist.append(InstructionFactory.createLoad(Type.LONG, slot));
//栈顶两个元素进行减法操作,结果保存在栈顶
// 调用long的减法指令,弹出2个long值,并把结果压入operand stack,现在operand stack的top第一个是long,第二个是out的引用
ilist.append(InstructionConstants.LSUB);
ilist.append(ifact.createInvoke("java.io.PrintStream",
"print", Type.VOID, new Type[]{Type.LONG},
Constants.INVOKEVIRTUAL));//消耗一个out,和减法的结果
// 将String对象" ms."放入pgen,并把其在pgen的引用(这个引用其实是字符串在常量池中的索引下标)压入operand stack(供out.print(Sting)调用的参数)
ilist.append(new PUSH(pgen," ms."));//常量入栈,首先会判断常量池中是否有此字符串
ilist.append(ifact.createInvoke("java.io.PrintStream",
"println", Type.VOID, new Type[]{Type.STRING},
Constants.INVOKEVIRTUAL));//消耗调最后一个out和刚入栈的" ms."
//如果返回类型不为void,则将返回结果入栈并返回
if(returnType != Type.VOID){
//处理返回值,如果不为空,从本地局部对象堆栈的slot+2位置读取指定类型的返回值压入operand stack
ilist.append(InstructionFactory.createLoad(returnType, slot+2));
}
ilist.append(InstructionFactory.createReturn(returnType));//根据相应的返回类型创建相应的返回指令
//finalize the construted method
wrapgen.stripAttributes(true);
wrapgen.setMaxStack();
wrapgen.setMaxLocals();
cgen.addMethod(wrapgen.getMethod());
ilist.dispose();
/**//*
* ifact.createPrintln(s)
*
* public InstructionList createPrintln( String s ) {
InstructionList il = new InstructionList();
int out = cp.addFieldref("java.lang.System", "out", "Ljava/io/PrintStream;");
int println = cp.addMethodref("java.io.PrintStream", "println", "(Ljava/lang/String;)V");
il.append(new GETSTATIC(out));
il.append(new PUSH(cp, s));
il.append(new INVOKEVIRTUAL(println));
return il;
}
*/
}
/** *//**
* @param args
*/
public static void main(String[] args) {
args[0]="D:\\java to eclipse\\javaeclipsestudy\\workspace\\BCELTest\\bin\\StringBuilder.class";
args[1]="buildString";
String targetClassfile = "StringBuilder.class";
if(args.length==2 && args[0].endsWith(".class")){
try{
JavaClass jclas = new ClassParser(args[0]).parse();
ClassGen cgen = new ClassGen(jclas);
Method[] methods = jclas.getMethods();
int index;
for(index =0;index<methods.length;index++){
if(methods[index].getName().equals(args[1])){
break;
}
}
if(index<methods.length){
addWrapper(cgen,methods[index]);
FileOutputStream fos = new FileOutputStream(targetClassfile);
cgen.getJavaClass().dump(fos);
fos.close();
}else{
System.err.println("Method " + args[1]+"not found in"+ args[0]);
}
}catch(Exception e){
e.printStackTrace();
}
}else{
System.out.println("usage: class-file method-name");
}
}
}
public class StringBuilder
{
private String buildString$impl(int length) {
String result = "";
for (int i = 0; i < length; i++) {
result += (char)(i%26 + 'a');
}
return result;
}
private String buildString(int length) {
long start = System.currentTimeMillis();
String result = buildString$impl(length);
System.out.println("Call to buildString$impl took " +
(System.currentTimeMillis()-start) + " ms.");
return result;
}
public static void main(String[] argv) {
StringBuilder inst = new StringBuilder();
for (int i = 0; i < argv.length; i++) {
String result = inst.buildString(Integer.parseInt(argv[i]));
System.out.println("Constructed string of length " +
result.length());
}
}
}
字节码
--------------------------------
33
-------------------------------- 33
0
2
CONSTANT_Utf8[ 1 ]( " SourceFile " )
true
CONSTANT_Utf8[ 1 ]( " StringBuilder.java " )
1
StringBuilder.java
StringBuilder.java
---------------------------------------------------------------------------
1 :CONSTANT_Class[ 7 ](name_index = 2 )
2 :CONSTANT_Utf8[ 1 ]( " StringBuilder " )
3 :CONSTANT_Class[ 7 ](name_index = 4 )
4 :CONSTANT_Utf8[ 1 ]( " java/lang/Object " )
5 :CONSTANT_Utf8[ 1 ]( " <init> " )
6 :CONSTANT_Utf8[ 1 ]( " ()V " )
7 :CONSTANT_Utf8[ 1 ]( " Code " )
8 :CONSTANT_Methodref[ 10 ](class_index = 3 , name_and_type_index = 9 )
9 :CONSTANT_NameAndType[ 12 ](name_index = 5 , signature_index = 6 )
10 :CONSTANT_Utf8[ 1 ]( " LineNumberTable " )
11 :CONSTANT_Utf8[ 1 ]( " LocalVariableTable " )
12 :CONSTANT_Utf8[ 1 ]( " this " )
13 :CONSTANT_Utf8[ 1 ]( " LStringBuilder; " )
14 :CONSTANT_Utf8[ 1 ]( " buildString$impl " )
15 :CONSTANT_Utf8[ 1 ]( " (I)Ljava/lang/String; " )
16 :CONSTANT_String[ 8 ](string_index = 17 )
17 :CONSTANT_Utf8[ 1 ]( "" )
18 :CONSTANT_Class[ 7 ](name_index = 19 )
19 :CONSTANT_Utf8[ 1 ]( " java/lang/StringBuilder " )
20 :CONSTANT_Methodref[ 10 ](class_index = 21 , name_and_type_index = 23 )
21 :CONSTANT_Class[ 7 ](name_index = 22 )
22 :CONSTANT_Utf8[ 1 ]( " java/lang/String " )
23 :CONSTANT_NameAndType[ 12 ](name_index = 24 , signature_index = 25 )
24 :CONSTANT_Utf8[ 1 ]( " valueOf " )
25 :CONSTANT_Utf8[ 1 ]( " (Ljava/lang/Object;)Ljava/lang/String; " )
26 :CONSTANT_Methodref[ 10 ](class_index = 18 , name_and_type_index = 27 )
27 :CONSTANT_NameAndType[ 12 ](name_index = 5 , signature_index = 28 )
28 :CONSTANT_Utf8[ 1 ]( " (Ljava/lang/String;)V " )
29 :CONSTANT_Methodref[ 10 ](class_index = 18 , name_and_type_index = 30 )
30 :CONSTANT_NameAndType[ 12 ](name_index = 31 , signature_index = 32 )
31 :CONSTANT_Utf8[ 1 ]( " append " )
32 :CONSTANT_Utf8[ 1 ]( " (C)Ljava/lang/StringBuilder; " )
33 :CONSTANT_Methodref[ 10 ](class_index = 18 , name_and_type_index = 34 )
34 :CONSTANT_NameAndType[ 12 ](name_index = 35 , signature_index = 36 )
35 :CONSTANT_Utf8[ 1 ]( " toString " )
36 :CONSTANT_Utf8[ 1 ]( " ()Ljava/lang/String; " )
37 :CONSTANT_Utf8[ 1 ]( " length " )
38 :CONSTANT_Utf8[ 1 ]( " I " )
39 :CONSTANT_Utf8[ 1 ]( " result " )
40 :CONSTANT_Utf8[ 1 ]( " Ljava/lang/String; " )
41 :CONSTANT_Utf8[ 1 ]( " i " )
42 :CONSTANT_Utf8[ 1 ]( " buildString " )
43 :CONSTANT_Methodref[ 10 ](class_index = 44 , name_and_type_index = 46 )
44 :CONSTANT_Class[ 7 ](name_index = 45 )
45 :CONSTANT_Utf8[ 1 ]( " java/lang/System " )
46 :CONSTANT_NameAndType[ 12 ](name_index = 47 , signature_index = 48 )
47 :CONSTANT_Utf8[ 1 ]( " currentTimeMillis " )
48 :CONSTANT_Utf8[ 1 ]( " ()J " )
49 :CONSTANT_Methodref[ 10 ](class_index = 1 , name_and_type_index = 50 )
50 :CONSTANT_NameAndType[ 12 ](name_index = 14 , signature_index = 15 )
51 :CONSTANT_Fieldref[ 9 ](class_index = 44 , name_and_type_index = 52 )
**********************************************************************
cc.toString : CONSTANT_Class[ 7 ](name_index = 45 )
java / lang / System
cnat.toString : CONSTANT_NameAndType[ 12 ](name_index = 53 , signature_index = 54 )
out
Ljava / io / PrintStream;
**********************************************************************
52 :CONSTANT_NameAndType[ 12 ](name_index = 53 , signature_index = 54 )
53 :CONSTANT_Utf8[ 1 ]( " out " )
54 :CONSTANT_Utf8[ 1 ]( " Ljava/io/PrintStream; " )
55 :CONSTANT_String[ 8 ](string_index = 56 )
56 :CONSTANT_Utf8[ 1 ]( " Call to buildString$impl took " )
57 :CONSTANT_Methodref[ 10 ](class_index = 18 , name_and_type_index = 58 )
58 :CONSTANT_NameAndType[ 12 ](name_index = 31 , signature_index = 59 )
59 :CONSTANT_Utf8[ 1 ]( " (J)Ljava/lang/StringBuilder; " )
60 :CONSTANT_String[ 8 ](string_index = 61 )
61 :CONSTANT_Utf8[ 1 ]( " ms. " )
62 :CONSTANT_Methodref[ 10 ](class_index = 18 , name_and_type_index = 63 )
63 :CONSTANT_NameAndType[ 12 ](name_index = 31 , signature_index = 64 )
64 :CONSTANT_Utf8[ 1 ]( " (Ljava/lang/String;)Ljava/lang/StringBuilder; " )
65 :CONSTANT_Methodref[ 10 ](class_index = 66 , name_and_type_index = 68 )
66 :CONSTANT_Class[ 7 ](name_index = 67 )
67 :CONSTANT_Utf8[ 1 ]( " java/io/PrintStream " )
68 :CONSTANT_NameAndType[ 12 ](name_index = 69 , signature_index = 28 )
69 :CONSTANT_Utf8[ 1 ]( " println " )
70 :CONSTANT_Utf8[ 1 ]( " start " )
71 :CONSTANT_Utf8[ 1 ]( " J " )
72 :CONSTANT_Utf8[ 1 ]( " main " )
73 :CONSTANT_Utf8[ 1 ]( " ([Ljava/lang/String;)V " )
74 :CONSTANT_Methodref[ 10 ](class_index = 1 , name_and_type_index = 9 )
75 :CONSTANT_Methodref[ 10 ](class_index = 76 , name_and_type_index = 78 )
76 :CONSTANT_Class[ 7 ](name_index = 77 )
77 :CONSTANT_Utf8[ 1 ]( " java/lang/Integer " )
78 :CONSTANT_NameAndType[ 12 ](name_index = 79 , signature_index = 80 )
79 :CONSTANT_Utf8[ 1 ]( " parseInt " )
80 :CONSTANT_Utf8[ 1 ]( " (Ljava/lang/String;)I " )
81 :CONSTANT_Methodref[ 10 ](class_index = 1 , name_and_type_index = 82 )
82 :CONSTANT_NameAndType[ 12 ](name_index = 42 , signature_index = 15 )
83 :CONSTANT_String[ 8 ](string_index = 84 )
84 :CONSTANT_Utf8[ 1 ]( " Constructed string of length " )
85 :CONSTANT_Methodref[ 10 ](class_index = 21 , name_and_type_index = 86 )
86 :CONSTANT_NameAndType[ 12 ](name_index = 37 , signature_index = 87 )
87 :CONSTANT_Utf8[ 1 ]( " ()I " )
88 :CONSTANT_Methodref[ 10 ](class_index = 18 , name_and_type_index = 89 )
89 :CONSTANT_NameAndType[ 12 ](name_index = 31 , signature_index = 90 )
90 :CONSTANT_Utf8[ 1 ]( " (I)Ljava/lang/StringBuilder; " )
91 :CONSTANT_Utf8[ 1 ]( " argv " )
92 :CONSTANT_Utf8[ 1 ]( " [Ljava/lang/String; " )
93 :CONSTANT_Utf8[ 1 ]( " inst " )
94 :CONSTANT_Utf8[ 1 ]( " SourceFile " )
95 :CONSTANT_Utf8[ 1 ]( " StringBuilder.java " )
------------------------------------------------------
------------------------------------------------------
start method method method -----------------------------------
方法访问标志
1
方法访问名称
me[i].getName() < init >
CONSTANT_Utf8[ 1 ]( " <init> " )
方法签名
()V
CONSTANT_Utf8[ 1 ]( " ()V " )
方法的参数类型
[Lorg.apache.bcel.generic.Type;@54172f
方法的返回类型
void
方法的Code
public void < init > ()
Code(max_stack = 1 , max_locals = 1 , code_length = 5 )
0 : aload_0
1 : invokespecial java.lang.Object. < init > ()V ( 8 )
4 : return
Attribute(s) =
LineNumber( 0 , 2 )
LocalVariable(start_pc = 0 , length = 5 , index = 0 :StringBuilder this )
end method method method -----------------------------------
start method method method -----------------------------------
方法访问标志
2
方法访问名称
me[i].getName() buildString$impl
CONSTANT_Utf8[ 1 ]( " buildString$impl " )
方法签名
(I)Ljava / lang / String;
CONSTANT_Utf8[ 1 ]( " (I)Ljava/lang/String; " )
方法的参数类型
[Lorg.apache.bcel.generic.Type;@1ed2ae8
方法的返回类型
java.lang.String
方法的Code
private String buildString$impl( int length)
Code(max_stack = 3 , max_locals = 4 , code_length = 44 )
0 : ldc "" ( 16 )
2 : astore_2
3 : iconst_0
4 : istore_3
5 : goto # 37
8 : new < java.lang.StringBuilder > ( 18 )
11 : dup
12 : aload_2
13 : invokestatic java.lang.String.valueOf (Ljava / lang / Object;)Ljava / lang / String; ( 20 )
16 : invokespecial java.lang.StringBuilder. < init > (Ljava / lang / String;)V ( 26 )
19 : iload_3
20 : bipush 26
22 : irem
23 : bipush 97
25 : iadd
26 : i2c
27 : invokevirtual java.lang.StringBuilder.append (C)Ljava / lang / StringBuilder; ( 29 )
30 : invokevirtual java.lang.StringBuilder.toString ()Ljava / lang / String; ( 33 )
33 : astore_2
34 : iinc % 3 1
37 : iload_3
38 : iload_1
39 : if_icmplt # 8
42 : aload_2
43 : areturn
Attribute(s) =
LineNumber( 0 , 5 ), LineNumber( 3 , 6 ), LineNumber( 8 , 7 ), LineNumber( 34 , 6 ),
LineNumber( 42 , 9 )
LocalVariable(start_pc = 0 , length = 44 , index = 0 :StringBuilder this )
LocalVariable(start_pc = 0 , length = 44 , index = 1 : int length)
LocalVariable(start_pc = 3 , length = 41 , index = 2 :String result)
LocalVariable(start_pc = 5 , length = 37 , index = 3 : int i)
end method method method -----------------------------------
start method method method -----------------------------------
方法访问标志
2
方法访问名称
me[i].getName() buildString
CONSTANT_Utf8[ 1 ]( " buildString " )
方法签名
(I)Ljava / lang / String;
CONSTANT_Utf8[ 1 ]( " (I)Ljava/lang/String; " )
方法的参数类型
[Lorg.apache.bcel.generic.Type;@19c26f5
方法的返回类型
java.lang.String
方法的Code
private String buildString( int length)
Code(max_stack = 6 , max_locals = 5 , code_length = 45 )
0 : invokestatic java.lang.System.currentTimeMillis ()J ( 43 )
3 : lstore_2
4 : aload_0
5 : iload_1
6 : invokespecial StringBuilder.buildString$impl (I)Ljava / lang / String; ( 49 )
9 : astore % 4
11 : getstatic java.lang.System.out Ljava / io / PrintStream; ( 51 )
14 : new < java.lang.StringBuilder > ( 18 )
17 : dup
18 : ldc " Call to buildString$impl took " ( 55 )
20 : invokespecial java.lang.StringBuilder. < init > (Ljava / lang / String;)V ( 26 )
23 : invokestatic java.lang.System.currentTimeMillis ()J ( 43 )
26 : lload_2
27 : lsub
28 : invokevirtual java.lang.StringBuilder.append (J)Ljava / lang / StringBuilder; ( 57 )
31 : ldc " ms. " ( 60 )
33 : invokevirtual java.lang.StringBuilder.append (Ljava / lang / String;)Ljava / lang / StringBuilder; ( 62 )
36 : invokevirtual java.lang.StringBuilder.toString ()Ljava / lang / String; ( 33 )
39 : invokevirtual java.io.PrintStream.println (Ljava / lang / String;)V ( 65 )
42 : aload % 4
44 : areturn
Attribute(s) =
LineNumber( 0 , 13 ), LineNumber( 4 , 14 ), LineNumber( 11 , 15 ), LineNumber( 23 , 16 ),
LineNumber( 39 , 15 ), LineNumber( 42 , 17 )
LocalVariable(start_pc = 0 , length = 45 , index = 0 :StringBuilder this )
LocalVariable(start_pc = 0 , length = 45 , index = 1 : int length)
LocalVariable(start_pc = 4 , length = 41 , index = 2 : long start)
LocalVariable(start_pc = 11 , length = 34 , index = 4 :String result)
end method method method -----------------------------------
start method method method -----------------------------------
方法访问标志
9
方法访问名称
me[i].getName() main
CONSTANT_Utf8[ 1 ]( " main " )
方法签名
([Ljava / lang / String;)V
CONSTANT_Utf8[ 1 ]( " ([Ljava/lang/String;)V " )
方法的参数类型
[Lorg.apache.bcel.generic.Type;@c1b531
方法的返回类型
void
方法的Code
public static void main(String[] argv)
Code(max_stack = 4 , max_locals = 4 , code_length = 59 )
0 : new < StringBuilder > ( 1 )
3 : dup
4 : invokespecial StringBuilder. < init > ()V ( 74 )
7 : astore_1
8 : iconst_0
9 : istore_2
10 : goto # 52
13 : aload_1
14 : aload_0
15 : iload_2
16 : aaload
17 : invokestatic java.lang.Integer.parseInt (Ljava / lang / String;)I ( 75 )
20 : invokespecial StringBuilder.buildString (I)Ljava / lang / String; ( 81 )
23 : astore_3
24 : getstatic java.lang.System.out Ljava / io / PrintStream; ( 51 )
27 : new < java.lang.StringBuilder > ( 18 )
30 : dup
31 : ldc " Constructed string of length " ( 83 )
33 : invokespecial java.lang.StringBuilder. < init > (Ljava / lang / String;)V ( 26 )
36 : aload_3
37 : invokevirtual java.lang.String.length ()I ( 85 )
40 : invokevirtual java.lang.StringBuilder.append (I)Ljava / lang / StringBuilder; ( 88 )
43 : invokevirtual java.lang.StringBuilder.toString ()Ljava / lang / String; ( 33 )
46 : invokevirtual java.io.PrintStream.println (Ljava / lang / String;)V ( 65 )
49 : iinc % 2 1
52 : iload_2
53 : aload_0
54 : arraylength
55 : if_icmplt # 13
58 : return
Attribute(s) =
LineNumber( 0 , 21 ), LineNumber( 8 , 22 ), LineNumber( 13 , 23 ), LineNumber( 24 , 24 ),
LineNumber( 36 , 25 ), LineNumber( 46 , 24 ), LineNumber( 49 , 22 ), LineNumber( 58 , 27 )
LocalVariable(start_pc = 0 , length = 59 , index = 0 :String[] argv)
LocalVariable(start_pc = 8 , length = 51 , index = 1 :StringBuilder inst)
LocalVariable(start_pc = 10 , length = 48 , index = 2 : int i)
LocalVariable(start_pc = 24 , length = 25 , index = 3 :String result)
end method method method -----------------------------------
-------------------------------- 33
0
2
CONSTANT_Utf8[ 1 ]( " SourceFile " )
true
CONSTANT_Utf8[ 1 ]( " StringBuilder.java " )
1
StringBuilder.java
StringBuilder.java
---------------------------------------------------------------------------
1 :CONSTANT_Class[ 7 ](name_index = 2 )
2 :CONSTANT_Utf8[ 1 ]( " StringBuilder " )
3 :CONSTANT_Class[ 7 ](name_index = 4 )
4 :CONSTANT_Utf8[ 1 ]( " java/lang/Object " )
5 :CONSTANT_Utf8[ 1 ]( " <init> " )
6 :CONSTANT_Utf8[ 1 ]( " ()V " )
7 :CONSTANT_Utf8[ 1 ]( " Code " )
8 :CONSTANT_Methodref[ 10 ](class_index = 3 , name_and_type_index = 9 )
9 :CONSTANT_NameAndType[ 12 ](name_index = 5 , signature_index = 6 )
10 :CONSTANT_Utf8[ 1 ]( " LineNumberTable " )
11 :CONSTANT_Utf8[ 1 ]( " LocalVariableTable " )
12 :CONSTANT_Utf8[ 1 ]( " this " )
13 :CONSTANT_Utf8[ 1 ]( " LStringBuilder; " )
14 :CONSTANT_Utf8[ 1 ]( " buildString$impl " )
15 :CONSTANT_Utf8[ 1 ]( " (I)Ljava/lang/String; " )
16 :CONSTANT_String[ 8 ](string_index = 17 )
17 :CONSTANT_Utf8[ 1 ]( "" )
18 :CONSTANT_Class[ 7 ](name_index = 19 )
19 :CONSTANT_Utf8[ 1 ]( " java/lang/StringBuilder " )
20 :CONSTANT_Methodref[ 10 ](class_index = 21 , name_and_type_index = 23 )
21 :CONSTANT_Class[ 7 ](name_index = 22 )
22 :CONSTANT_Utf8[ 1 ]( " java/lang/String " )
23 :CONSTANT_NameAndType[ 12 ](name_index = 24 , signature_index = 25 )
24 :CONSTANT_Utf8[ 1 ]( " valueOf " )
25 :CONSTANT_Utf8[ 1 ]( " (Ljava/lang/Object;)Ljava/lang/String; " )
26 :CONSTANT_Methodref[ 10 ](class_index = 18 , name_and_type_index = 27 )
27 :CONSTANT_NameAndType[ 12 ](name_index = 5 , signature_index = 28 )
28 :CONSTANT_Utf8[ 1 ]( " (Ljava/lang/String;)V " )
29 :CONSTANT_Methodref[ 10 ](class_index = 18 , name_and_type_index = 30 )
30 :CONSTANT_NameAndType[ 12 ](name_index = 31 , signature_index = 32 )
31 :CONSTANT_Utf8[ 1 ]( " append " )
32 :CONSTANT_Utf8[ 1 ]( " (C)Ljava/lang/StringBuilder; " )
33 :CONSTANT_Methodref[ 10 ](class_index = 18 , name_and_type_index = 34 )
34 :CONSTANT_NameAndType[ 12 ](name_index = 35 , signature_index = 36 )
35 :CONSTANT_Utf8[ 1 ]( " toString " )
36 :CONSTANT_Utf8[ 1 ]( " ()Ljava/lang/String; " )
37 :CONSTANT_Utf8[ 1 ]( " length " )
38 :CONSTANT_Utf8[ 1 ]( " I " )
39 :CONSTANT_Utf8[ 1 ]( " result " )
40 :CONSTANT_Utf8[ 1 ]( " Ljava/lang/String; " )
41 :CONSTANT_Utf8[ 1 ]( " i " )
42 :CONSTANT_Utf8[ 1 ]( " buildString " )
43 :CONSTANT_Methodref[ 10 ](class_index = 44 , name_and_type_index = 46 )
44 :CONSTANT_Class[ 7 ](name_index = 45 )
45 :CONSTANT_Utf8[ 1 ]( " java/lang/System " )
46 :CONSTANT_NameAndType[ 12 ](name_index = 47 , signature_index = 48 )
47 :CONSTANT_Utf8[ 1 ]( " currentTimeMillis " )
48 :CONSTANT_Utf8[ 1 ]( " ()J " )
49 :CONSTANT_Methodref[ 10 ](class_index = 1 , name_and_type_index = 50 )
50 :CONSTANT_NameAndType[ 12 ](name_index = 14 , signature_index = 15 )
51 :CONSTANT_Fieldref[ 9 ](class_index = 44 , name_and_type_index = 52 )
**********************************************************************
cc.toString : CONSTANT_Class[ 7 ](name_index = 45 )
java / lang / System
cnat.toString : CONSTANT_NameAndType[ 12 ](name_index = 53 , signature_index = 54 )
out
Ljava / io / PrintStream;
**********************************************************************
52 :CONSTANT_NameAndType[ 12 ](name_index = 53 , signature_index = 54 )
53 :CONSTANT_Utf8[ 1 ]( " out " )
54 :CONSTANT_Utf8[ 1 ]( " Ljava/io/PrintStream; " )
55 :CONSTANT_String[ 8 ](string_index = 56 )
56 :CONSTANT_Utf8[ 1 ]( " Call to buildString$impl took " )
57 :CONSTANT_Methodref[ 10 ](class_index = 18 , name_and_type_index = 58 )
58 :CONSTANT_NameAndType[ 12 ](name_index = 31 , signature_index = 59 )
59 :CONSTANT_Utf8[ 1 ]( " (J)Ljava/lang/StringBuilder; " )
60 :CONSTANT_String[ 8 ](string_index = 61 )
61 :CONSTANT_Utf8[ 1 ]( " ms. " )
62 :CONSTANT_Methodref[ 10 ](class_index = 18 , name_and_type_index = 63 )
63 :CONSTANT_NameAndType[ 12 ](name_index = 31 , signature_index = 64 )
64 :CONSTANT_Utf8[ 1 ]( " (Ljava/lang/String;)Ljava/lang/StringBuilder; " )
65 :CONSTANT_Methodref[ 10 ](class_index = 66 , name_and_type_index = 68 )
66 :CONSTANT_Class[ 7 ](name_index = 67 )
67 :CONSTANT_Utf8[ 1 ]( " java/io/PrintStream " )
68 :CONSTANT_NameAndType[ 12 ](name_index = 69 , signature_index = 28 )
69 :CONSTANT_Utf8[ 1 ]( " println " )
70 :CONSTANT_Utf8[ 1 ]( " start " )
71 :CONSTANT_Utf8[ 1 ]( " J " )
72 :CONSTANT_Utf8[ 1 ]( " main " )
73 :CONSTANT_Utf8[ 1 ]( " ([Ljava/lang/String;)V " )
74 :CONSTANT_Methodref[ 10 ](class_index = 1 , name_and_type_index = 9 )
75 :CONSTANT_Methodref[ 10 ](class_index = 76 , name_and_type_index = 78 )
76 :CONSTANT_Class[ 7 ](name_index = 77 )
77 :CONSTANT_Utf8[ 1 ]( " java/lang/Integer " )
78 :CONSTANT_NameAndType[ 12 ](name_index = 79 , signature_index = 80 )
79 :CONSTANT_Utf8[ 1 ]( " parseInt " )
80 :CONSTANT_Utf8[ 1 ]( " (Ljava/lang/String;)I " )
81 :CONSTANT_Methodref[ 10 ](class_index = 1 , name_and_type_index = 82 )
82 :CONSTANT_NameAndType[ 12 ](name_index = 42 , signature_index = 15 )
83 :CONSTANT_String[ 8 ](string_index = 84 )
84 :CONSTANT_Utf8[ 1 ]( " Constructed string of length " )
85 :CONSTANT_Methodref[ 10 ](class_index = 21 , name_and_type_index = 86 )
86 :CONSTANT_NameAndType[ 12 ](name_index = 37 , signature_index = 87 )
87 :CONSTANT_Utf8[ 1 ]( " ()I " )
88 :CONSTANT_Methodref[ 10 ](class_index = 18 , name_and_type_index = 89 )
89 :CONSTANT_NameAndType[ 12 ](name_index = 31 , signature_index = 90 )
90 :CONSTANT_Utf8[ 1 ]( " (I)Ljava/lang/StringBuilder; " )
91 :CONSTANT_Utf8[ 1 ]( " argv " )
92 :CONSTANT_Utf8[ 1 ]( " [Ljava/lang/String; " )
93 :CONSTANT_Utf8[ 1 ]( " inst " )
94 :CONSTANT_Utf8[ 1 ]( " SourceFile " )
95 :CONSTANT_Utf8[ 1 ]( " StringBuilder.java " )
------------------------------------------------------
------------------------------------------------------
start method method method -----------------------------------
方法访问标志
1
方法访问名称
me[i].getName() < init >
CONSTANT_Utf8[ 1 ]( " <init> " )
方法签名
()V
CONSTANT_Utf8[ 1 ]( " ()V " )
方法的参数类型
[Lorg.apache.bcel.generic.Type;@54172f
方法的返回类型
void
方法的Code
public void < init > ()
Code(max_stack = 1 , max_locals = 1 , code_length = 5 )
0 : aload_0
1 : invokespecial java.lang.Object. < init > ()V ( 8 )
4 : return
Attribute(s) =
LineNumber( 0 , 2 )
LocalVariable(start_pc = 0 , length = 5 , index = 0 :StringBuilder this )
end method method method -----------------------------------
start method method method -----------------------------------
方法访问标志
2
方法访问名称
me[i].getName() buildString$impl
CONSTANT_Utf8[ 1 ]( " buildString$impl " )
方法签名
(I)Ljava / lang / String;
CONSTANT_Utf8[ 1 ]( " (I)Ljava/lang/String; " )
方法的参数类型
[Lorg.apache.bcel.generic.Type;@1ed2ae8
方法的返回类型
java.lang.String
方法的Code
private String buildString$impl( int length)
Code(max_stack = 3 , max_locals = 4 , code_length = 44 )
0 : ldc "" ( 16 )
2 : astore_2
3 : iconst_0
4 : istore_3
5 : goto # 37
8 : new < java.lang.StringBuilder > ( 18 )
11 : dup
12 : aload_2
13 : invokestatic java.lang.String.valueOf (Ljava / lang / Object;)Ljava / lang / String; ( 20 )
16 : invokespecial java.lang.StringBuilder. < init > (Ljava / lang / String;)V ( 26 )
19 : iload_3
20 : bipush 26
22 : irem
23 : bipush 97
25 : iadd
26 : i2c
27 : invokevirtual java.lang.StringBuilder.append (C)Ljava / lang / StringBuilder; ( 29 )
30 : invokevirtual java.lang.StringBuilder.toString ()Ljava / lang / String; ( 33 )
33 : astore_2
34 : iinc % 3 1
37 : iload_3
38 : iload_1
39 : if_icmplt # 8
42 : aload_2
43 : areturn
Attribute(s) =
LineNumber( 0 , 5 ), LineNumber( 3 , 6 ), LineNumber( 8 , 7 ), LineNumber( 34 , 6 ),
LineNumber( 42 , 9 )
LocalVariable(start_pc = 0 , length = 44 , index = 0 :StringBuilder this )
LocalVariable(start_pc = 0 , length = 44 , index = 1 : int length)
LocalVariable(start_pc = 3 , length = 41 , index = 2 :String result)
LocalVariable(start_pc = 5 , length = 37 , index = 3 : int i)
end method method method -----------------------------------
start method method method -----------------------------------
方法访问标志
2
方法访问名称
me[i].getName() buildString
CONSTANT_Utf8[ 1 ]( " buildString " )
方法签名
(I)Ljava / lang / String;
CONSTANT_Utf8[ 1 ]( " (I)Ljava/lang/String; " )
方法的参数类型
[Lorg.apache.bcel.generic.Type;@19c26f5
方法的返回类型
java.lang.String
方法的Code
private String buildString( int length)
Code(max_stack = 6 , max_locals = 5 , code_length = 45 )
0 : invokestatic java.lang.System.currentTimeMillis ()J ( 43 )
3 : lstore_2
4 : aload_0
5 : iload_1
6 : invokespecial StringBuilder.buildString$impl (I)Ljava / lang / String; ( 49 )
9 : astore % 4
11 : getstatic java.lang.System.out Ljava / io / PrintStream; ( 51 )
14 : new < java.lang.StringBuilder > ( 18 )
17 : dup
18 : ldc " Call to buildString$impl took " ( 55 )
20 : invokespecial java.lang.StringBuilder. < init > (Ljava / lang / String;)V ( 26 )
23 : invokestatic java.lang.System.currentTimeMillis ()J ( 43 )
26 : lload_2
27 : lsub
28 : invokevirtual java.lang.StringBuilder.append (J)Ljava / lang / StringBuilder; ( 57 )
31 : ldc " ms. " ( 60 )
33 : invokevirtual java.lang.StringBuilder.append (Ljava / lang / String;)Ljava / lang / StringBuilder; ( 62 )
36 : invokevirtual java.lang.StringBuilder.toString ()Ljava / lang / String; ( 33 )
39 : invokevirtual java.io.PrintStream.println (Ljava / lang / String;)V ( 65 )
42 : aload % 4
44 : areturn
Attribute(s) =
LineNumber( 0 , 13 ), LineNumber( 4 , 14 ), LineNumber( 11 , 15 ), LineNumber( 23 , 16 ),
LineNumber( 39 , 15 ), LineNumber( 42 , 17 )
LocalVariable(start_pc = 0 , length = 45 , index = 0 :StringBuilder this )
LocalVariable(start_pc = 0 , length = 45 , index = 1 : int length)
LocalVariable(start_pc = 4 , length = 41 , index = 2 : long start)
LocalVariable(start_pc = 11 , length = 34 , index = 4 :String result)
end method method method -----------------------------------
start method method method -----------------------------------
方法访问标志
9
方法访问名称
me[i].getName() main
CONSTANT_Utf8[ 1 ]( " main " )
方法签名
([Ljava / lang / String;)V
CONSTANT_Utf8[ 1 ]( " ([Ljava/lang/String;)V " )
方法的参数类型
[Lorg.apache.bcel.generic.Type;@c1b531
方法的返回类型
void
方法的Code
public static void main(String[] argv)
Code(max_stack = 4 , max_locals = 4 , code_length = 59 )
0 : new < StringBuilder > ( 1 )
3 : dup
4 : invokespecial StringBuilder. < init > ()V ( 74 )
7 : astore_1
8 : iconst_0
9 : istore_2
10 : goto # 52
13 : aload_1
14 : aload_0
15 : iload_2
16 : aaload
17 : invokestatic java.lang.Integer.parseInt (Ljava / lang / String;)I ( 75 )
20 : invokespecial StringBuilder.buildString (I)Ljava / lang / String; ( 81 )
23 : astore_3
24 : getstatic java.lang.System.out Ljava / io / PrintStream; ( 51 )
27 : new < java.lang.StringBuilder > ( 18 )
30 : dup
31 : ldc " Constructed string of length " ( 83 )
33 : invokespecial java.lang.StringBuilder. < init > (Ljava / lang / String;)V ( 26 )
36 : aload_3
37 : invokevirtual java.lang.String.length ()I ( 85 )
40 : invokevirtual java.lang.StringBuilder.append (I)Ljava / lang / StringBuilder; ( 88 )
43 : invokevirtual java.lang.StringBuilder.toString ()Ljava / lang / String; ( 33 )
46 : invokevirtual java.io.PrintStream.println (Ljava / lang / String;)V ( 65 )
49 : iinc % 2 1
52 : iload_2
53 : aload_0
54 : arraylength
55 : if_icmplt # 13
58 : return
Attribute(s) =
LineNumber( 0 , 21 ), LineNumber( 8 , 22 ), LineNumber( 13 , 23 ), LineNumber( 24 , 24 ),
LineNumber( 36 , 25 ), LineNumber( 46 , 24 ), LineNumber( 49 , 22 ), LineNumber( 58 , 27 )
LocalVariable(start_pc = 0 , length = 59 , index = 0 :String[] argv)
LocalVariable(start_pc = 8 , length = 51 , index = 1 :StringBuilder inst)
LocalVariable(start_pc = 10 , length = 48 , index = 2 : int i)
LocalVariable(start_pc = 24 , length = 25 , index = 3 :String result)
end method method method -----------------------------------