隨筆-204  評論-149  文章-0  trackbacks-0

          有了前幾篇關于BCEL的使用,現(xiàn)在API轉換的問題其實很簡單了
          實際API轉換要做的比這個例子要復雜些,涉及到包名,類名,方法名稱等的變化。把常量池變化搞清楚就夠了

          假如這是APIa中的一個類
          實際只提供APIa的jar包,不提供源代碼

          package one.api;

          public class MyAPITest {
              
              
          public int add(String a,String b){
                  
          return new Integer(a).intValue()+new Integer(b).intValue();
              }


          }


          如下是APIb的相對應的類,注意兩個APIa提供的類層次結構,類的名稱已經方法的名稱是一致的

          package one.api;

          public class MyAPITest {
              
              
          public int add(int a,int b){
                  
          return a+b;
              }


          }


          現(xiàn)在有一個應用程序使用的是APIa的類來寫的,并且只提供classes文件,
          假如現(xiàn)在把此應用程序放在另一臺機器上運行,但是此機器上只能提供APIb的jar包,要想此應用程序能夠在此機器上運行,則要修改應用程序的classes字節(jié)碼。
          應用程序的代碼如下:
          package client;

          import one.api.MyAPITest;

          public class ClientTest {

              
          /**
               * 
          @param args
               
          */

              
          public static void main(String[] args) {
                  
                  MyAPITest sb = new MyAPITest();
                  int result = sb.add("1", "2");

                  System.out.println(result);
                  

              }

              
              
          public int mytest(String a,String b){
                  MyAPITest sb = new MyAPITest();
                  int result = sb.add(a, b);

                  
          return result;
              }


          }


          則要調用sb.add(a, b);的地方將方法的參數(shù)改為整型的
          本來的指令序列如下
           ldc  "1" 
           ldc  "2" 
           invokevirtual one.api.MyAPITest.add (Ljava/lang/String;Ljava/lang/String;)I

          則將字節(jié)碼的內容加入
           ldc  "1" 
           invokestatic java.lang.Integer.parseInt(Ljava/lang/String;)I
           ldc  "2" 
           invokestatic java.lang.Integer.parseInt(Ljava/lang/String;)I
           invokevirtual one.api.MyAPITest.add (II)I
          紅色的指令是將操作數(shù)棧的棧頂元素由字符串改變?yōu)檎?br /> 并且還需要把調用的方法的新的方法簽名加入到常量池Constant_Pool中
          1,這個在原來的指令序列中插入轉換指令需要插入的地方,但方法的參數(shù)比較明確時如add("1","2")或者add(s1,s2),s1,s2是局部變量,這個插入的地方比較好早。但是當方法的參數(shù)是直接調用其他方法的而產生返回結果時,還需要往指令前找其他方法的調用指令以及這個其他方法有幾個參數(shù),在這個其他方法調用后將這個其他方法的返回結果進行整型轉換。
          說的有的亂,假如main方法中為如下時
              public static void main(String[] args) {
                  
                  MyAPITest sb 
          = new MyAPITest();
                  
                  
          int result = sb.add("1""2");
                  System.out.println(result);
                  
                  String temp = "999";
                  int resultone = sb.add(temp, "33");
                  System.out.println(resultone);

                  
                  
          int resulttwo = sb.add(String.valueOf("1"), String.valueOf("2"));
                  System.out.println(resulttwo);

                  
          int resultthree = sb.add(StringUtil.createStringOne("111"),"333");
                  System.out.println(resultthree);
                  
                  
          int resultfour = sb.add(StringUtil.createStringTwo("23", "34"),StringUtil.createStringThree("12", "23", "34"));
                  System.out.println(resultfour);

                  
                  
          int resultfive = sb.add(StringUtil.createStringTwo(StringUtil.createStringOne("88"), "34"),StringUtil.createStringThree("12", "23", "34"));
                  System.out.println(resultfive);

              }

          上面的指令序列為如下:
          完整的code.toString的信息
          public static void main(String[] args)
          Code(max_stack 
          = 5, max_locals = 9, code_length = 153)
          0:    new        <one.api.MyAPITest> (16)
          3:    dup
          4:    invokespecial    one.api.MyAPITest.<init> ()V (18)
          7:    astore_1
          8:    aload_1
          9:    ldc        "1" (19)
          11:   ldc        "2" (21)
          13:   invokevirtual    one.api.MyAPITest.add (Ljava/lang/String;Ljava/lang/String;)I (23)
          16:   istore_2
          17:   getstatic        java.lang.System.out Ljava/io/PrintStream; (27)
          20:   iload_2
          21:   invokevirtual    java.io.PrintStream.println (I)V (33)
          24:   ldc        "999" (39)
          26:   astore_3
          27:   aload_1
          28:   aload_3
           invokestatic java.lang.Integer.parseInt(Ljava/lang/String;)I
          29:   ldc        "33" (41)
          invokestatic java.lang.Integer.parseInt(Ljava/lang/String;)I
          31:   invokevirtual    one.api.MyAPITest.add (Ljava/lang/String;Ljava/lang/String;)I (23)

          34:   istore        %4
          36:   getstatic        java.lang.System.out Ljava/io/PrintStream; (27)
          39:   iload        %4
          41:   invokevirtual    java.io.PrintStream.println (I)V (33)
          44:   aload_1
          45:   ldc        "1" (19)
          47:   invokestatic    java.lang.String.valueOf (Ljava/lang/Object;)Ljava/lang/String; (43)
          50:   ldc        "2" (21)
          52:   invokestatic    java.lang.String.valueOf (Ljava/lang/Object;)Ljava/lang/String; (43)
          55:   invokevirtual    one.api.MyAPITest.add (Ljava/lang/String;Ljava/lang/String;)I (23)
          58:   istore        %5
          60:   getstatic        java.lang.System.out Ljava/io/PrintStream; (27)
          63:   iload        %5
          65:   invokevirtual    java.io.PrintStream.println (I)V (33)
          68:   aload_1
          69:   ldc        "111" (49)
          71:   invokestatic    client.StringUtil.createStringOne (Ljava/lang/String;)Ljava/lang/String; (51)
          74:   ldc        "333" (57)
          76:   invokevirtual    one.api.MyAPITest.add (Ljava/lang/String;Ljava/lang/String;)I (23)
          79:   istore        %6
          81:   getstatic        java.lang.System.out Ljava/io/PrintStream; (27)
          84:   iload        %6
          86:   invokevirtual    java.io.PrintStream.println (I)V (33)
          89:   aload_1
          90:   ldc        "23" (59)
          92:   ldc        "34" (61)
          94:   invokestatic    client.StringUtil.createStringTwo (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; (63)
          invokestatic java.lang.Integer.parseInt(Ljava/lang/String;)I
          97:   ldc        "12" (67)
          99:   ldc        "23" (59)
          101:  ldc        "34" (61)
          103:  invokestatic    client.StringUtil.createStringThree (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; (69)
          invokestatic java.lang.Integer.parseInt(Ljava/lang/String;)I
          106:  invokevirtual    one.api.MyAPITest.add (Ljava/lang/String;Ljava/lang/String;)I (23)
          109:  istore        %7
          111:  getstatic        java.lang.System.out Ljava/io/PrintStream; (27)
          114:  iload        %7
          116:  invokevirtual    java.io.PrintStream.println (I)V (33)
          119:  aload_1
          120:  ldc        "88" (73)
          122:  invokestatic    client.StringUtil.createStringOne (Ljava/lang/String;)Ljava/lang/String; (51)
          125:  ldc        "34" (61)
          127:  invokestatic    client.StringUtil.createStringTwo (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; (63)
          invokestatic java.lang.Integer.parseInt(Ljava/lang/String;)I
          130:  ldc        "12" (67)
          132:  ldc        "23" (59)
          134:  ldc        "34" (61)
          136:  invokestatic    client.StringUtil.createStringThree (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; (69)
          invokestatic java.lang.Integer.parseInt(Ljava/lang/String;)I
          139:  invokevirtual    one.api.MyAPITest.add (Ljava/lang/String;Ljava/lang/String;)I (23)
          142:  istore        %8
          144:  getstatic        java.lang.System.out Ljava/io/PrintStream; (27)
          147:  iload        %8
          149:  invokevirtual    java.io.PrintStream.println (I)V (33)
          152:  return

          Attribute(s) 
          = 
          LineNumber(
          012), LineNumber(814), LineNumber(1715), LineNumber(2417), 
          LineNumber(
          2718), LineNumber(3619), LineNumber(4421), LineNumber(6022), 
          LineNumber(
          6824), LineNumber(8125), LineNumber(8927), LineNumber(11128), 
          LineNumber(
          11930), LineNumber(14431), LineNumber(15232)
          LocalVariable(start_pc 
          = 0, length = 153, index = 0:String[] args)
          LocalVariable(start_pc 
          = 8, length = 145, index = 1:one.api.MyAPITest sb)
          LocalVariable(start_pc 
          = 17, length = 136, index = 2:int result)
          LocalVariable(start_pc 
          = 27, length = 126, index = 3:String temp)
          LocalVariable(start_pc 
          = 36, length = 117, index = 4:int resultone)
          LocalVariable(start_pc 
          = 60, length = 93, index = 5:int resulttwo)
          LocalVariable(start_pc 
          = 81, length = 72, index = 6:int resultthree)
          LocalVariable(start_pc 
          = 111, length = 42, index = 7:int resultfour)
          LocalVariable(start_pc 
          = 144, length = 9, index = 8:int resultfive)

          看int resultone = sb.add(temp, "33");
          要找對應的這個插入地方,首先需要判斷第一個參數(shù)是局部變量使用的aload指令,第二個參數(shù)是直接LDC的
          而對于
          int resultfour = sb.add(StringUtil.createStringTwo("23", "34"),StringUtil.createStringThree("12", "23", "34"));
          add的參數(shù)都是由方法調用的,需要知道在調用add的指令前有幾個invokeXXX指令,然后判斷這些指令有幾個參數(shù),然后選擇合適的地方來插入,總之要根據(jù)方法調用的參數(shù)個數(shù)往前找插入的地方,這個雖然可以實現(xiàn),但是實現(xiàn)起來比較麻煩,不是一個好的辦法。
          2.我比較推崇的方法時,但調用add時,此時但卻操作棧的前幾個數(shù)肯定是add的參數(shù),只需要對這些數(shù)進行轉換即可,但是要創(chuàng)建額外的局部變量來保存中間結果,當參數(shù)都轉換完時,在把這些自己創(chuàng)建的局部變量壓入操作棧中,這些操作都在add所對應的invokevirtual指令前,當調用invokevirtual時,操作數(shù)棧的前幾個元素已經是整型了
          package transmit;

          import java.util.ArrayList;
          import java.util.HashMap;
          import java.util.List;
          import java.util.Map;

          import org.apache.bcel.Constants;
          import org.apache.bcel.classfile.ClassParser;
          import org.apache.bcel.classfile.Constant;
          import org.apache.bcel.classfile.ConstantClass;
          import org.apache.bcel.classfile.ConstantFieldref;
          import org.apache.bcel.classfile.ConstantMethodref;
          import org.apache.bcel.classfile.ConstantNameAndType;
          import org.apache.bcel.classfile.ConstantPool;
          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.INVOKEVIRTUAL;
          import org.apache.bcel.generic.Instruction;
          import org.apache.bcel.generic.InstructionFactory;
          import org.apache.bcel.generic.InstructionHandle;
          import org.apache.bcel.generic.InstructionList;
          import org.apache.bcel.generic.LocalVariableGen;
          import org.apache.bcel.generic.MethodGen;
          import org.apache.bcel.generic.Type;

          public class ChangeUsingBcel {

              
          /*
               * 掃描StringBuilder的各個方法的指令序列,在其中找Invokexxxx指令,
               * 看此指令在常量池中引用的方法引用是否是要其前后加代碼的方法
               * 方法所在的類要一致,方法的名稱要一致,方法的簽名要一致
               * 
               
          */

              
              
          /**
               * 
               * 
          @param cgen 要被解析的類class文件
               * 
          @param classname 要被修改的方法所在的類名稱,若有包名,則為java/lang/Object類似的one/api/MyAPITest
               * 
          @param methodname 要被修改的方法的名稱add
               * 
          @param methodSignature 要被修改的方法的簽名(Ljava/lang/String;Ljava/lang/String;)I
               * 
               * Map.put(classname,list.add(map.put(
               
          */

              
          private static void modifyWrapper(ClassGen cgen,String classname,String methodname,String methodSignature){
                  
                  InstructionFactory ifact 
          = new InstructionFactory(cgen);
                  ConstantPoolGen pgen 
          = cgen.getConstantPool();
                  
                  ConstantPool pool 
          = pgen.getConstantPool();
                  
                  
                  
                  
          //留作它用
                  Map<String,List> map = new HashMap<String,List>();
                  List list 
          = new ArrayList();
                  list.add((
          new HashMap()).put(methodname, methodSignature));
                  map.put(classname, list);
                  
                  
          /*
                   * 先查查此類的常量池中是否有 MyAPITest的引用
                   *常量池的0號索引沒有使用
                   
          */

                  Map classrefMap 
          = new HashMap();
                  Map methodrefMap 
          = new HashMap();
                  Map fieldrefMap 
          = new HashMap();
                  
                  
                  
                  System.out.println(
          "pool.getLength()   "+pool.getLength());//1024不是實際的條數(shù)
                  Constant[] constants = pool.getConstantPool();
                  System.out.println(
          "constants.length   "+constants.length);//1024
                  for(int cN=1;cN<constants.length;cN++){
                      Constant tempCon 
          = pool.getConstant(cN);
                      
          if(tempCon!=null && tempCon.getTag()==Constants.CONSTANT_Class){
                          ConstantClass tempConClass 
          = (ConstantClass)tempCon;
                          String classSignature 
          = tempConClass.getBytes(pool);// one/api/MyAPITest
                          if(classSignature.equals("one/api/MyAPITest")){
                              
          //池中有此class的引用,然后判斷方法引用或域引用的class_index為此類的index
                              int class_index = cN;
                              classrefMap.put(class_index, classSignature);
                              
          /*
                               * 再次遍歷常量池找
                               
          */

                              
          for(int cN2=1;cN2<constants.length;cN2++){
                                  Constant temp 
          = pool.getConstant(cN2);
                                  System.out.println(temp);
                                  
          if(temp!=null && temp.getTag()==Constants.CONSTANT_Methodref){
                                      ConstantMethodref cmr 
          = (ConstantMethodref)temp;
                                      
          if(cmr.getClassIndex()==class_index){
                                          ConstantNameAndType cnat 
          = (ConstantNameAndType)pool.getConstant(cmr.getNameAndTypeIndex());
                                          System.out.println(
          "方法的名稱 "+cnat.getName(pool));
                                          System.out.println(
          "方法的簽名 "+cnat.getSignature(pool));
                                          methodrefMap.put(cnat.getName(pool), cnat.getSignature(pool));
          //                                pool.constantToString(index, tag)
          //                                pool.constantToString(c)
                                      }

                                  }

                                  
          if(temp!=null && temp.getTag()==Constants.CONSTANT_Fieldref){
                                      ConstantFieldref cfr 
          = (ConstantFieldref)temp;
                                      
          if(cfr.getClassIndex()==class_index){
                                          ConstantNameAndType cnat 
          = (ConstantNameAndType)pool.getConstant(cfr.getNameAndTypeIndex());
                                          System.out.println(
          "引用的域的名稱 "+cnat.getName(pool));
                                          System.out.println(
          "引用的域的簽名 "+cnat.getSignature(pool));
                                          fieldrefMap.put(cnat.getName(pool), cnat.getSignature(pool));
                                      }

                                  }

                              }

                              
                          }

                      }

                  }

                  
                  
                  
          /*
                   * 分析類的各個方法,在各個方法中找出調用語句
                   
          */

                  
                  String cname 
          = cgen.getClassName();
                  
                  
                  
                  Method[] methods 
          = cgen.getMethods();
                  
          for(int i=0;i<methods.length;i++){
                      Method tempMethod 
          = methods[i];
                      
                      MethodGen tempMethodGen 
          = new MethodGen(tempMethod,cname,pgen);
                      
                      InstructionList tempList 
          = tempMethodGen.getInstructionList();
                      System.out.println(
          "tempList.getLength()            "+tempList.getLength());;
                      
          //Instruction[] tempInstructions = tempList.getInstructions();
                      InstructionHandle[] tempInHandles = tempList.getInstructionHandles();
                      System.out.println(
          "tempInHandles.length            "+tempInHandles.length);
                      
                      
          for(int j=0;j<tempInHandles.length;j++){
                          InstructionHandle ihandle 
          = tempInHandles[j];
                          Instruction nowInstruction 
          = ihandle.getInstruction();
                          
          if(nowInstruction.getOpcode()==Constants.INVOKEVIRTUAL){
                              INVOKEVIRTUAL invokeVirtual 
          = (INVOKEVIRTUAL)nowInstruction;
                              ConstantMethodref cmr 
          = (ConstantMethodref)pgen.getConstant(invokeVirtual.getIndex());
                              
                              
                              
                              ConstantClass cc 
          = (ConstantClass)pgen.getConstant(cmr.getClassIndex());
                              String nowClassName 
          = cc.getBytes(pgen.getConstantPool());
                              ConstantNameAndType cnt 
          = (ConstantNameAndType)pgen.getConstant(cmr.getNameAndTypeIndex());
                              String nowMethodName 
          = cnt.getName(pgen.getConstantPool());
                              String nowMethodSignature 
          = cnt.getSignature(pgen.getConstantPool());
                              
                              
          //判斷此方法的所屬的類,方法的名稱,方法的簽名是否與所要加的一致(I)Ljava/lang/String;
                              
          //不加方法簽名的話,當類中有重載方法時不好辦,加的話,if中當遇到第一個時又把其給改掉了,后面的invokexxx的方法簽名是改后的了,因此這樣的簽名的方法也要加上指令
                              if(nowClassName.equals(classname) && nowMethodName.equals(methodname) && (nowMethodSignature.equals(methodSignature)||(nowMethodSignature.equals("(II)I")))){
                                  
                                  cgen.removeMethod(tempMethodGen.getMethod());
                                  
                                  InstructionList addList 
          = new InstructionList();
                                  addList.append(ifact.createInvoke(
          "java.lang.Integer""parseInt", Type.INT, new Type[]{Type.STRING}, Constants.INVOKESTATIC));
                                  
          //這個局部變量的作用范圍如何確定,還是簡簡單單的設置成null表示從開放開始到結束
                                  LocalVariableGen lvg = tempMethodGen.addLocalVariable("paramTwoint", Type.INT, nullnull);
                                  
          //把當前棧的整型結果保存到局部變量中
                                  addList.append(ifact.createStore(Type.INT, lvg.getIndex()));
                                  
                                  
          //再轉換第一個字符參數(shù)
                                  addList.append(ifact.createInvoke("java.lang.Integer""parseInt", Type.INT, new Type[]{Type.STRING}, Constants.INVOKESTATIC));
          //                        LocalVariableGen lvg2 = tempMethodGen.addLocalVariable("paramOneint", Type.INT, null, null);
          //                        ifact.createStore(Type.INT, lvg2.getIndex());
          //                        
          //                        //再把兩個整型局部局部加到棧中
          //                        ifact.createLoad(Type.INT, lvg2.getIndex());
                                  addList.append(ifact.createLoad(Type.INT, lvg.getIndex()));
                                  
                                  
          //將指令插入到invokeVirtual之前
                                  tempList.insert(ihandle, addList);
                                  
                                  
          //修改方法的簽名到(II)I
                                  
          //可以保留原來的Methodref,使用addMethodref來添加新的methodref
                                  
          //原來的methodref根本就沒有用,其實可以從常量池刪除調
          //                        int newMethodIndex = pgen.addMethodref("one.api.MyAPITest", "add", "(II)I");
          //                        invokeVirtual.setIndex(newMethodIndex);
                                  
                                  
                                  
          //在if語句中改的話,后面的調用都不會被加代碼了
                                  
          //或者自己加一個NameAndType這樣還避免沖突,然后把新的下標賦給原來的方法引用
                                  int new_name_and_type_index = pgen.addNameAndType("add""(II)I");
                                  cmr.setNameAndTypeIndex(new_name_and_type_index);
                                  
          //假如方法的class_index也發(fā)生了變化,則也可以
          //                        int new_class_index = pgen.addClass(str);
          //                        cmr.setClassIndex(class_index);
                                  
                                  
                                  
          //finalize the construted method
                                  tempMethodGen.stripAttributes(false);
                                  tempMethodGen.setMaxStack();
                                  tempMethodGen.setMaxLocals();

                                  cgen.addMethod(tempMethodGen.getMethod());
                                  
                                  System.out.println(tempMethodGen.getInstructionList());
                                  System.out.println();
                                  System.out.println();
                                  
                                  
                              }

                              
                              
          if(nowClassName.equals(classname) && nowMethodName.equals(""&& nowMethodSignature.equals("")){
                                  
          //此類中的其他方法的改動
                                  
          //
                              }

                              
                              
                          }

                          
                          
          //此類中的使用到classname類中的域
                          if(nowInstruction.getOpcode()==Constants.GETFIELD){
                              
          //..
                          }

                      }

                      
          //            tempList.setPositions();
          //            tempList.findHandle(pos);
                      
                  }

                      
              }


              
          /**
               * 
          @param args
               
          */

              
          public static void main(String[] args) {
                  
                  args[
          0]="D:\\java to eclipse\\javaeclipsestudy\\workspace\\BCELTest\\bin\\client\\ClientTest.class";
                  
                  
          if(args.length==1 && args[0].endsWith(".class")){
                      
          try{
                          JavaClass jclas 
          = new ClassParser(args[0]).parse();
                          
                          ClassGen cgen 
          = new ClassGen(jclas);
                          
                          modifyWrapper(cgen,
          "one/api/MyAPITest","add","(Ljava/lang/String;Ljava/lang/String;)I");
                          
                          
                          cgen.getJavaClass().dump(args[
          0]);
                      }
          catch(Exception e){
                          e.printStackTrace();
                      }

                  }
          else{
                      System.out.println(
          "usage: class-file");
                  }


              }



          }


          改變字節(jié)碼的片段
          129:  aload_1
          130:  ldc  "23" (59)
          132:  ldc  "34" (61)
          134:  invokestatic client.StringUtil.createStringTwo (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; (63)
          137:  ldc  "12" (67)
          139:  ldc  "23" (59)
          141:  ldc  "34" (61)
          143:  invokestatic client.StringUtil.createStringThree (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String; (69)
          146:  invokestatic java.lang.Integer.parseInt (Ljava/lang/String;)I (98)
          149:  istore  %13
          151:  invokestatic java.lang.Integer.parseInt (Ljava/lang/String;)I (98)
          154:  iload  %13
          156:  invokevirtual one.api.MyAPITest.add (II)I (23)

          posted on 2009-08-16 19:30 Frank_Fang 閱讀(1812) 評論(2)  編輯  收藏 所屬分類: bcel javassist

          評論:
          # re: API轉換的問題的解決 2009-08-16 23:38 | Frank_Fang
          藍色的指令是采用方法1所加的位置,這樣做不太方便
            回復  更多評論
            
          # re: API轉換的問題的解決 2009-08-17 21:54 | Frank_Fang
          使用反編譯工具根據(jù)生成的class文件生成的java文件
          // Decompiled by Jad v1.5.8e2. Copyright 2001 Pavel Kouznetsov.
          // Jad home page: http://kpdus.tripod.com/jad.html
          // Decompiler options: packimports(3) fieldsfirst ansi space
          // Source File Name: ClientTest.java

          package client;

          import java.io.PrintStream;
          import one.api.MyAPITest;

          // Referenced classes of package client:
          // StringUtil

          public class ClientTest
          {

          public ClientTest()
          {
          }

          public static void main(String args[])
          {
          MyAPITest sb = new MyAPITest();
          int paramTwoint = Integer.parseInt("2");
          int result = sb.add(Integer.parseInt("1"), paramTwoint);
          System.out.println(result);
          String temp = "999";
          int paramTwoint = Integer.parseInt("33");
          int resultone = sb.add(Integer.parseInt(temp), paramTwoint);
          System.out.println(resultone);
          int paramTwoint = Integer.parseInt(String.valueOf("2"));
          int resulttwo = sb.add(Integer.parseInt(String.valueOf("1")), paramTwoint);
          System.out.println(resulttwo);
          int paramTwoint = Integer.parseInt("333");
          int resultthree = sb.add(Integer.parseInt(StringUtil.createStringOne("111")), paramTwoint);
          System.out.println(resultthree);
          int paramTwoint = Integer.parseInt(StringUtil.createStringThree("12", "23", "34"));
          int resultfour = sb.add(Integer.parseInt(StringUtil.createStringTwo("23", "34")), paramTwoint);
          System.out.println(resultfour);
          int paramTwoint = Integer.parseInt(StringUtil.createStringThree("12", "23", "34"));
          int resultfive = sb.add(Integer.parseInt(StringUtil.createStringTwo(StringUtil.createStringOne("88"), "34")), paramTwoint);
          System.out.println(resultfive);
          }

          public int mytest(String a, String b)
          {
          MyAPITest sb = new MyAPITest();
          int paramTwoint = Integer.parseInt(b);
          int result = sb.add(Integer.parseInt(a), paramTwoint);
          return result;
          }
          }  回復  更多評論
            
          主站蜘蛛池模板: 荣成市| 宝兴县| 遵义市| 桂林市| 大名县| 大洼县| 青海省| 民乐县| 临夏县| 清新县| 长垣县| 徐州市| 乌苏市| 垦利县| 通道| 高唐县| 大名县| 邵武市| 芮城县| 遵义市| 中西区| 柳江县| 密云县| 尤溪县| 项城市| 都江堰市| 涿鹿县| 如皋市| 库伦旗| 上栗县| 古田县| 永修县| 丰县| 吕梁市| 高邑县| 灵璧县| 松江区| 论坛| 米易县| 九江县| 桑日县|