javap 没有显示预期的方法

逆向工程 拆卸 爪哇
2021-07-01 08:15:52

我正在尝试为名为“findbugs”的 Java 工具编写自定义签名。我要检测的具体示例是实例化静态、非并发哈希图的实例。在多线程环境中,这会导致 bad things™ 的发生。

这是我的java源代码:

import java.util.HashMap;
import java.util.Map;


public class StaticInitializationOfHashMap {
    private static Map<String,String> hashMap;

    private static void init() throws Exception {
        hashMap = new HashMap<String,String>();
        for(int x = 0; x < 1000; x++) {
            hashMap.put("Key_" + x, "Value_" + x);
        }
    }

    public static void main(String[] args) throws Exception {
        init();
        for(int i = 0; i < hashMap.size(); ++i) {
            System.out.println(hashMap.get("Key_" + i));
        }
    }
}

这是我的 javap -c -v 输出:

Classfile /c:/gitRepos/findbugs/findbugsTestCases/build/classes/StaticInitializationOfHashMap.class
  Last modified Oct 27, 2015; size 1478 bytes
  MD5 checksum d1b1e57f69d1b13f658ee996fc2bbd24
  Compiled from "StaticInitializationOfHashMap.java"
public class StaticInitializationOfHashMap
  SourceFile: "StaticInitializationOfHashMap.java"
  minor version: 0
  major version: 51
  flags: ACC_PUBLIC, ACC_SUPER

Constant pool:
   #1 = Methodref          #20.#45        //  java/lang/Object."<init>":()V
   #2 = Class              #46            //  java/util/HashMap
   #3 = Methodref          #2.#45         //  java/util/HashMap."<init>":()V
   #4 = Fieldref           #19.#47        //  StaticInitializationOfHashMap.hashMap:Ljava/util/Map;
   #5 = Class              #48            //  java/lang/StringBuilder
   #6 = Methodref          #5.#45         //  java/lang/StringBuilder."<init>":()V
   #7 = String             #49            //  Key_
   #8 = Methodref          #5.#50         //  java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
   #9 = Methodref          #5.#51         //  java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
  #10 = Methodref          #5.#52         //  java/lang/StringBuilder.toString:()Ljava/lang/String;
  #11 = String             #53            //  Value_
  #12 = InterfaceMethodref #54.#55        //  java/util/Map.put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
  #13 = Methodref          #19.#56        //  StaticInitializationOfHashMap.init:()V
  #14 = InterfaceMethodref #54.#57        //  java/util/Map.size:()I
  #15 = Fieldref           #58.#59        //  java/lang/System.out:Ljava/io/PrintStream;
  #16 = InterfaceMethodref #54.#60        //  java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
  #17 = Class              #61            //  java/lang/String
  #18 = Methodref          #62.#63        //  java/io/PrintStream.println:(Ljava/lang/String;)V
  #19 = Class              #64            //  StaticInitializationOfHashMap
  #20 = Class              #65            //  java/lang/Object
  #21 = Utf8               hashMap
  #22 = Utf8               Ljava/util/Map;
  #23 = Utf8               Signature
  #24 = Utf8               Ljava/util/Map<Ljava/lang/String;Ljava/lang/String;>;
  #25 = Utf8               <init>
  #26 = Utf8               ()V
  #27 = Utf8               Code
  #28 = Utf8               LineNumberTable
  #29 = Utf8               LocalVariableTable
  #30 = Utf8               this
  #31 = Utf8               LStaticInitializationOfHashMap;
  #32 = Utf8               init
  #33 = Utf8               x
  #34 = Utf8               I
  #35 = Utf8               StackMapTable
  #36 = Utf8               Exceptions
  #37 = Class              #66            //  java/lang/Exception
  #38 = Utf8               main
  #39 = Utf8               ([Ljava/lang/String;)V
  #40 = Utf8               i
  #41 = Utf8               args
  #42 = Utf8               [Ljava/lang/String;
  #43 = Utf8               SourceFile
  #44 = Utf8               StaticInitializationOfHashMap.java
  #45 = NameAndType        #25:#26        //  "<init>":()V
  #46 = Utf8               java/util/HashMap
  #47 = NameAndType        #21:#22        //  hashMap:Ljava/util/Map;
  #48 = Utf8               java/lang/StringBuilder
  #49 = Utf8               Key_
  #50 = NameAndType        #67:#68        //  append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
  #51 = NameAndType        #67:#69        //  append:(I)Ljava/lang/StringBuilder;
  #52 = NameAndType        #70:#71        //  toString:()Ljava/lang/String;
  #53 = Utf8               Value_
  #54 = Class              #72            //  java/util/Map
  #55 = NameAndType        #73:#74        //  put:(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
  #56 = NameAndType        #32:#26        //  init:()V
  #57 = NameAndType        #75:#76        //  size:()I
  #58 = Class              #77            //  java/lang/System
  #59 = NameAndType        #78:#79        //  out:Ljava/io/PrintStream;
  #60 = NameAndType        #80:#81        //  get:(Ljava/lang/Object;)Ljava/lang/Object;
  #61 = Utf8               java/lang/String
  #62 = Class              #82            //  java/io/PrintStream
  #63 = NameAndType        #83:#84        //  println:(Ljava/lang/String;)V
  #64 = Utf8               StaticInitializationOfHashMap
  #65 = Utf8               java/lang/Object
  #66 = Utf8               java/lang/Exception
  #67 = Utf8               append
  #68 = Utf8               (Ljava/lang/String;)Ljava/lang/StringBuilder;
  #69 = Utf8               (I)Ljava/lang/StringBuilder;
  #70 = Utf8               toString
  #71 = Utf8               ()Ljava/lang/String;
  #72 = Utf8               java/util/Map
  #73 = Utf8               put
  #74 = Utf8               (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
  #75 = Utf8               size
  #76 = Utf8               ()I
  #77 = Utf8               java/lang/System
  #78 = Utf8               out
  #79 = Utf8               Ljava/io/PrintStream;
  #80 = Utf8               get
  #81 = Utf8               (Ljava/lang/Object;)Ljava/lang/Object;
  #82 = Utf8               java/io/PrintStream
  #83 = Utf8               println
  #84 = Utf8               (Ljava/lang/String;)V
{
  public StaticInitializationOfHashMap();
    flags: ACC_PUBLIC

    Code:
      stack=1, locals=1, args_size=1
         0: aload_0       
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: return        
      LineNumberTable:
        line 5: 0
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               0       5     0  this   LStaticInitializationOfHashMap;

  public static void main(java.lang.String[]) throws java.lang.Exception;
    flags: ACC_PUBLIC, ACC_STATIC

    Code:
      stack=4, locals=2, args_size=1
         0: invokestatic  #13                 // Method init:()V
         3: iconst_0      
         4: istore_1      
         5: iload_1       
         6: getstatic     #4                  // Field hashMap:Ljava/util/Map;
         9: invokeinterface #14,  1           // InterfaceMethod java/util/Map.size:()I
        14: if_icmpge     59
        17: getstatic     #15                 // Field java/lang/System.out:Ljava/io/PrintStream;
        20: getstatic     #4                  // Field hashMap:Ljava/util/Map;
        23: new           #5                  // class java/lang/StringBuilder
        26: dup           
        27: invokespecial #6                  // Method java/lang/StringBuilder."<init>":()V
        30: ldc           #7                  // String Key_
        32: invokevirtual #8                  // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
        35: iload_1       
        36: invokevirtual #9                  // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
        39: invokevirtual #10                 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
        42: invokeinterface #16,  2           // InterfaceMethod java/util/Map.get:(Ljava/lang/Object;)Ljava/lang/Object;
        47: checkcast     #17                 // class java/lang/String
        50: invokevirtual #18                 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
        53: iinc          1, 1
        56: goto          5
        59: return        
      LineNumberTable:
        line 16: 0
        line 17: 3
        line 18: 17
        line 17: 53
        line 20: 59
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
               5      54     1     i   I
               0      60     0  args   [Ljava/lang/String;
      StackMapTable: number_of_entries = 2
           frame_type = 252 /* append */
             offset_delta = 5
        locals = [ int ]
           frame_type = 250 /* chop */
          offset_delta = 53

    Exceptions:
      throws java.lang.Exception
}

0: invokestatic #13它看来,我们正在调用该init()方法,但是在我的拆装,我没有看到来叫反编译的方法的引用init

我究竟做错了什么?看来init方法直接优化到我的main方法了,但是我想,在使用Oracle产品的时候,所有的优化都推迟到了JIT而不是编译时?

1个回答

原来是我的问题:

您需要运行该命令javap -c -private <className>,否则 javap 默认不显示私有方法的反汇编。