ASM读取class信息

Stella981
• 阅读 823

Java asm读取class信息

[TOC]

1 class文件查看方式

1.1 使用jdk提供的javap命令

  • 1.1.1 javap

    javap 用法: javap 其中, 可能的选项包括: -help --help -? 输出此用法消息 -version 版本信息 -v -verbose 输出附加信息 -l 输出行号和本地变量表 -public 仅显示公共类和成员 -protected 显示受保护的/公共类和成员 -package 显示程序包/受保护的/公共类 和成员 (默认) -p -private 显示所有类和成员 -c 对代码进行反汇编 -s 输出内部类型签名 -sysinfo 显示正在处理的类的 系统信息 (路径, 大小, 日期, MD5 散列) -constants 显示最终常量 -classpath 指定查找用户类文件的位置 -cp 指定查找用户类文件的位置 -bootclasspath 覆盖引导类文件的位置

  • 1.1.2 使用javap命令查看项目中main.jar中的BusIndex.class

    javap -v -cp ./main.jar com.eventbus.gen.BusIndex

1.2 使用反编译工具Luyten

  • 1.2.1 用luyten打开main.jar

  • 1.2.2 选项Settings/Bytecode

  • 1.2.3 在Structure中选中BusIndex.class

1.3 反编译结果

javap -v -cp ./main.jar com.eventbus.gen.BusIndex
Classfile jar:file:/D:/projects/Sample/ASMSample/app/libs/main.jar!/com/eventbus/gen/BusIndex.class
  Last modified 2016-10-10; size 1193 bytes
  MD5 checksum 4ac635858d4c2533a29accf9d634f49b
  Compiled from "SourceFile"
public final class com.eventbus.gen.BusIndex extends com.a.a.c.a
  minor version: 0
  major version: 51
  flags: ACC_PUBLIC, ACC_FINAL, ACC_SUPER
Constant pool:
   #1 = String             #52            // showMessage
   #2 = String             #53            // showMessagedd
   #3 = Class              #38            // com/a/a/c/a
   #4 = Class              #39            // com/a/a/c/d
   #5 = Class              #40            // com/a/a/d/a
   #6 = Class              #41            // com/eventbus/gen/BusIndex
   #7 = Class              #42            // com/eventbus/gen/a
   #8 = Class              #43            // com/eventbus/gen/b
   #9 = Class              #44            // com/eventbus/gen/c
  #10 = Class              #45            // com/eventbus/gen/d
  #11 = Class              #46            // com/sample/app/Main2Activity
  #12 = Class              #47            // com/sample/app/MainActivity
  #13 = Class              #48            // com/sample/app/MainActivity$a
  #14 = Class              #51            // java/lang/Object
  #15 = Methodref          #3.#23         // com/a/a/c/a."<init>":()V
  #16 = Methodref          #4.#23         // com/a/a/c/d."<init>":()V
  #17 = Methodref          #4.#25         // com/a/a/c/d.a:(Ljava/lang/String;Ljava/lang/Class;Ljava/lang/Class;Lcom/a/a/b/a;)V
  #18 = Methodref          #7.#24         // com/eventbus/gen/a."<init>":(Lcom/eventbus/gen/BusIndex;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/Class;)V
  #19 = Methodref          #8.#24         // com/eventbus/gen/b."<init>":(Lcom/eventbus/gen/BusIndex;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/Class;)V
  #20 = Methodref          #9.#24         // com/eventbus/gen/c."<init>":(Lcom/eventbus/gen/BusIndex;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/Class;)V
  #21 = Methodref          #10.#24        // com/eventbus/gen/d."<init>":(Lcom/eventbus/gen/BusIndex;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/Class;)V
  #22 = Methodref          #14.#26        // java/lang/Object.getClass:()Ljava/lang/Class;
  #23 = NameAndType        #32:#28        // "<init>":()V
  #24 = NameAndType        #32:#29        // "<init>":(Lcom/eventbus/gen/BusIndex;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/Class;)V
  #25 = NameAndType        #37:#31        // a:(Ljava/lang/String;Ljava/lang/Class;Ljava/lang/Class;Lcom/a/a/b/a;)V
  #26 = NameAndType        #50:#27        // getClass:()Ljava/lang/Class;
  #27 = Utf8               ()Ljava/lang/Class;
  #28 = Utf8               ()V
  #29 = Utf8               (Lcom/eventbus/gen/BusIndex;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/Class;)V
  #30 = Utf8               (Ljava/lang/Object;)Lcom/a/a/c/d;
  #31 = Utf8               (Ljava/lang/String;Ljava/lang/Class;Ljava/lang/Class;Lcom/a/a/b/a;)V
  #32 = Utf8               <init>
  #33 = Utf8               Code
  #34 = Utf8               InnerClasses
  #35 = Utf8               LineNumberTable
  #36 = Utf8               SourceFile
  #37 = Utf8               a
  #38 = Utf8               com/a/a/c/a
  #39 = Utf8               com/a/a/c/d
  #40 = Utf8               com/a/a/d/a
  #41 = Utf8               com/eventbus/gen/BusIndex
  #42 = Utf8               com/eventbus/gen/a
  #43 = Utf8               com/eventbus/gen/b
  #44 = Utf8               com/eventbus/gen/c
  #45 = Utf8               com/eventbus/gen/d
  #46 = Utf8               com/sample/app/Main2Activity
  #47 = Utf8               com/sample/app/MainActivity
  #48 = Utf8               com/sample/app/MainActivity$a
  #49 = Utf8               generateSubscribeMethodIndex
  #50 = Utf8               getClass
  #51 = Utf8               java/lang/Object
  #52 = Utf8               showMessage
  #53 = Utf8               showMessagedd
{
  public com.eventbus.gen.BusIndex();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=1, locals=1, args_size=1
         0: aload_0
         1: invokespecial #15                 // Method com/a/a/c/a."<init>":()V
         4: return
      LineNumberTable:
        line 15: 0

  public com.a.a.c.d generateSubscribeMethodIndex(java.lang.Object);
    descriptor: (Ljava/lang/Object;)Lcom/a/a/c/d;
    flags: ACC_PUBLIC
    Code:
      stack=11, locals=7, args_size=2
         0: new           #4                  // class com/a/a/c/d
         3: dup
         4: invokespecial #16                 // Method com/a/a/c/d."<init>":()V
         7: astore_2
         8: aload_1
         9: invokevirtual #22                 // Method java/lang/Object.getClass:()Ljava/lang/Class;
        12: astore_3
        13: aconst_null
        14: astore        4
        16: aconst_null
        17: astore        5
        19: aconst_null
        20: astore        6
        22: aload_3
        23: ldc           #12                 // class com/sample/app/MainActivity
        25: if_acmpne     104
        28: ldc           #13                 // class com/sample/app/MainActivity$a
        30: astore        4
        32: ldc           #5                  // class com/a/a/d/a
        34: astore        5
        36: ldc           #1                  // String showMessage
        38: astore        6
        40: aload_2
        41: aload         6
        43: aload         4
        45: aload         5
        47: new           #7                  // class com/eventbus/gen/a
        50: dup
        51: aload_0
        52: aload_1
        53: aload         6
        55: aload         4
        57: aload         5
        59: invokespecial #18                 // Method com/eventbus/gen/a."<init>":(Lcom/eventbus/gen/BusIndex;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/Class;)V
        62: invokevirtual #17                 // Method com/a/a/c/d.a:(Ljava/lang/String;Ljava/lang/Class;Ljava/lang/Class;Lcom/a/a/b/a;)V
        65: ldc           #13                 // class com/sample/app/MainActivity$a
        67: astore        4
        69: ldc           #5                  // class com/a/a/d/a
        71: astore        5
        73: ldc           #2                  // String showMessagedd
        75: astore        6
        77: aload_2
        78: aload         6
        80: aload         4
        82: aload         5
        84: new           #8                  // class com/eventbus/gen/b
        87: dup
        88: aload_0
        89: aload_1
        90: aload         6
        92: aload         4
        94: aload         5
        96: invokespecial #19                 // Method com/eventbus/gen/b."<init>":(Lcom/eventbus/gen/BusIndex;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/Class;)V
        99: invokevirtual #17                 // Method com/a/a/c/d.a:(Ljava/lang/String;Ljava/lang/Class;Ljava/lang/Class;Lcom/a/a/b/a;)V
       102: aload_2
       103: areturn
       104: aload_3
       105: ldc           #11                 // class com/sample/app/Main2Activity
       107: if_acmpne     186
       110: ldc           #13                 // class com/sample/app/MainActivity$a
       112: astore        4
       114: ldc           #5                  // class com/a/a/d/a
       116: astore        5
       118: ldc           #1                  // String showMessage
       120: astore        6
       122: aload_2
       123: aload         6
       125: aload         4
       127: aload         5
       129: new           #9                  // class com/eventbus/gen/c
       132: dup
       133: aload_0
       134: aload_1
       135: aload         6
       137: aload         4
       139: aload         5
       141: invokespecial #20                 // Method com/eventbus/gen/c."<init>":(Lcom/eventbus/gen/BusIndex;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/Class;)V
       144: invokevirtual #17                 // Method com/a/a/c/d.a:(Ljava/lang/String;Ljava/lang/Class;Ljava/lang/Class;Lcom/a/a/b/a;)V
       147: ldc           #13                 // class com/sample/app/MainActivity$a
       149: astore        4
       151: ldc           #5                  // class com/a/a/d/a
       153: astore        5
       155: ldc           #2                  // String showMessagedd
       157: astore        6
       159: aload_2
       160: aload         6
       162: aload         4
       164: aload         5
       166: new           #10                 // class com/eventbus/gen/d
       169: dup
       170: aload_0
       171: aload_1
       172: aload         6
       174: aload         4
       176: aload         5
       178: invokespecial #21                 // Method com/eventbus/gen/d."<init>":(Lcom/eventbus/gen/BusIndex;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/Class;)V
       181: invokevirtual #17                 // Method com/a/a/c/d.a:(Ljava/lang/String;Ljava/lang/Class;Ljava/lang/Class;Lcom/a/a/b/a;)V
       184: aload_2
       185: areturn
       186: aload_2
       187: areturn
      LineNumberTable:
        line 18: 0
        line 19: 8
        line 20: 13
        line 21: 16
        line 22: 19
        line 23: 22
        line 24: 28
        line 25: 32
        line 26: 36
        line 27: 40
        line 33: 65
        line 34: 69
        line 35: 73
        line 36: 77
        line 42: 102
        line 44: 104
        line 45: 110
        line 46: 114
        line 47: 118
        line 48: 122
        line 54: 147
        line 55: 151
        line 56: 155
        line 57: 159
        line 63: 184
        line 65: 186
}
InnerClasses:
     #10; //class com/eventbus/gen/d
     #9; //class com/eventbus/gen/c
     #8; //class com/eventbus/gen/b
     #7; //class com/eventbus/gen/a
     public static #37= #13 of #12; //a=class com/sample/app/MainActivity$a of class com/sample/app/MainActivity
SourceFile: "SourceFile"

2 asm中与class中的指令和类型映射


2.1 Opcodes中的指令

public interface Opcodes {

    // ASM API versions

    int ASM4 = 4 << 16 | 0 << 8 | 0;
    int ASM5 = 5 << 16 | 0 << 8 | 0;
    int ASM6 = 6 << 16 | 0 << 8 | 0;

    // versions

    int V1_1 = 3 << 16 | 45;
    int V1_2 = 0 << 16 | 46;
    int V1_3 = 0 << 16 | 47;
    int V1_4 = 0 << 16 | 48;
    int V1_5 = 0 << 16 | 49;
    int V1_6 = 0 << 16 | 50;
    int V1_7 = 0 << 16 | 51;
    int V1_8 = 0 << 16 | 52;
    int V1_9 = 0 << 16 | 53;

    // access flags

    int ACC_PUBLIC = 0x0001; // class, field, method
    int ACC_PRIVATE = 0x0002; // class, field, method
    int ACC_PROTECTED = 0x0004; // class, field, method
    int ACC_STATIC = 0x0008; // field, method
    int ACC_FINAL = 0x0010; // class, field, method, parameter
    int ACC_SUPER = 0x0020; // class
    int ACC_SYNCHRONIZED = 0x0020; // method
    int ACC_VOLATILE = 0x0040; // field
    int ACC_BRIDGE = 0x0040; // method
    int ACC_VARARGS = 0x0080; // method
    int ACC_TRANSIENT = 0x0080; // field
    int ACC_NATIVE = 0x0100; // method
    int ACC_INTERFACE = 0x0200; // class
    int ACC_ABSTRACT = 0x0400; // class, method
    int ACC_STRICT = 0x0800; // method
    int ACC_SYNTHETIC = 0x1000; // class, field, method, parameter
    int ACC_ANNOTATION = 0x2000; // class
    int ACC_ENUM = 0x4000; // class(?) field inner
    int ACC_MANDATED = 0x8000; // parameter
    int ACC_MODULE = 0x8000; // class

    // ASM specific pseudo access flags

    int ACC_DEPRECATED = 0x20000; // class, field, method

    // types for NEWARRAY

    int T_BOOLEAN = 4;
    int T_CHAR = 5;
    int T_FLOAT = 6;
    int T_DOUBLE = 7;
    int T_BYTE = 8;
    int T_SHORT = 9;
    int T_INT = 10;
    int T_LONG = 11;

    // tags for Handle

    int H_GETFIELD = 1;
    int H_GETSTATIC = 2;
    int H_PUTFIELD = 3;
    int H_PUTSTATIC = 4;
    int H_INVOKEVIRTUAL = 5;
    int H_INVOKESTATIC = 6;
    int H_INVOKESPECIAL = 7;
    int H_NEWINVOKESPECIAL = 8;
    int H_INVOKEINTERFACE = 9;

    // stack map frame types

    /**
     * Represents an expanded frame. See {@link ClassReader#EXPAND_FRAMES}.
     */
    int F_NEW = -1;

    /**
     * Represents a compressed frame with complete frame data.
     */
    int F_FULL = 0;

    /**
     * Represents a compressed frame where locals are the same as the locals in
     * the previous frame, except that additional 1-3 locals are defined, and
     * with an empty stack.
     */
    int F_APPEND = 1;

    /**
     * Represents a compressed frame where locals are the same as the locals in
     * the previous frame, except that the last 1-3 locals are absent and with
     * an empty stack.
     */
    int F_CHOP = 2;

    /**
     * Represents a compressed frame with exactly the same locals as the
     * previous frame and with an empty stack.
     */
    int F_SAME = 3;

    /**
     * Represents a compressed frame with exactly the same locals as the
     * previous frame and with a single value on the stack.
     */
    int F_SAME1 = 4;

    // Do not try to change the following code to use auto-boxing,
    // these values are compared by reference and not by value
    // The constructor of Integer was deprecated in 9
    // but we are stuck with it by backward compatibility
    @SuppressWarnings("deprecation") Integer TOP = new Integer(0);
    @SuppressWarnings("deprecation") Integer INTEGER = new Integer(1);
    @SuppressWarnings("deprecation") Integer FLOAT = new Integer(2);
    @SuppressWarnings("deprecation") Integer DOUBLE = new Integer(3);
    @SuppressWarnings("deprecation") Integer LONG = new Integer(4);
    @SuppressWarnings("deprecation") Integer NULL = new Integer(5);
    @SuppressWarnings("deprecation") Integer UNINITIALIZED_THIS = new Integer(6);

    // opcodes // visit method (- = idem)

    int NOP = 0; // visitInsn
    int ACONST_NULL = 1; // -
    int ICONST_M1 = 2; // -
    int ICONST_0 = 3; // -
    int ICONST_1 = 4; // -
    int ICONST_2 = 5; // -
    int ICONST_3 = 6; // -
    int ICONST_4 = 7; // -
    int ICONST_5 = 8; // -
    int LCONST_0 = 9; // -
    int LCONST_1 = 10; // -
    int FCONST_0 = 11; // -
    int FCONST_1 = 12; // -
    int FCONST_2 = 13; // -
    int DCONST_0 = 14; // -
    int DCONST_1 = 15; // -
    int BIPUSH = 16; // visitIntInsn
    int SIPUSH = 17; // -
    int LDC = 18; // visitLdcInsn
    // int LDC_W = 19; // -
    // int LDC2_W = 20; // -
    int ILOAD = 21; // visitVarInsn
    int LLOAD = 22; // -
    int FLOAD = 23; // -
    int DLOAD = 24; // -
    int ALOAD = 25; // -
    // int ILOAD_0 = 26; // -
    // int ILOAD_1 = 27; // -
    // int ILOAD_2 = 28; // -
    // int ILOAD_3 = 29; // -
    // int LLOAD_0 = 30; // -
    // int LLOAD_1 = 31; // -
    // int LLOAD_2 = 32; // -
    // int LLOAD_3 = 33; // -
    // int FLOAD_0 = 34; // -
    // int FLOAD_1 = 35; // -
    // int FLOAD_2 = 36; // -
    // int FLOAD_3 = 37; // -
    // int DLOAD_0 = 38; // -
    // int DLOAD_1 = 39; // -
    // int DLOAD_2 = 40; // -
    // int DLOAD_3 = 41; // -
    // int ALOAD_0 = 42; // -
    // int ALOAD_1 = 43; // -
    // int ALOAD_2 = 44; // -
    // int ALOAD_3 = 45; // -
    int IALOAD = 46; // visitInsn
    int LALOAD = 47; // -
    int FALOAD = 48; // -
    int DALOAD = 49; // -
    int AALOAD = 50; // -
    int BALOAD = 51; // -
    int CALOAD = 52; // -
    int SALOAD = 53; // -
    int ISTORE = 54; // visitVarInsn
    int LSTORE = 55; // -
    int FSTORE = 56; // -
    int DSTORE = 57; // -
    int ASTORE = 58; // -
    // int ISTORE_0 = 59; // -
    // int ISTORE_1 = 60; // -
    // int ISTORE_2 = 61; // -
    // int ISTORE_3 = 62; // -
    // int LSTORE_0 = 63; // -
    // int LSTORE_1 = 64; // -
    // int LSTORE_2 = 65; // -
    // int LSTORE_3 = 66; // -
    // int FSTORE_0 = 67; // -
    // int FSTORE_1 = 68; // -
    // int FSTORE_2 = 69; // -
    // int FSTORE_3 = 70; // -
    // int DSTORE_0 = 71; // -
    // int DSTORE_1 = 72; // -
    // int DSTORE_2 = 73; // -
    // int DSTORE_3 = 74; // -
    // int ASTORE_0 = 75; // -
    // int ASTORE_1 = 76; // -
    // int ASTORE_2 = 77; // -
    // int ASTORE_3 = 78; // -
    int IASTORE = 79; // visitInsn
    int LASTORE = 80; // -
    int FASTORE = 81; // -
    int DASTORE = 82; // -
    int AASTORE = 83; // -
    int BASTORE = 84; // -
    int CASTORE = 85; // -
    int SASTORE = 86; // -
    int POP = 87; // -
    int POP2 = 88; // -
    int DUP = 89; // -
    int DUP_X1 = 90; // -
    int DUP_X2 = 91; // -
    int DUP2 = 92; // -
    int DUP2_X1 = 93; // -
    int DUP2_X2 = 94; // -
    int SWAP = 95; // -
    int IADD = 96; // -
    int LADD = 97; // -
    int FADD = 98; // -
    int DADD = 99; // -
    int ISUB = 100; // -
    int LSUB = 101; // -
    int FSUB = 102; // -
    int DSUB = 103; // -
    int IMUL = 104; // -
    int LMUL = 105; // -
    int FMUL = 106; // -
    int DMUL = 107; // -
    int IDIV = 108; // -
    int LDIV = 109; // -
    int FDIV = 110; // -
    int DDIV = 111; // -
    int IREM = 112; // -
    int LREM = 113; // -
    int FREM = 114; // -
    int DREM = 115; // -
    int INEG = 116; // -
    int LNEG = 117; // -
    int FNEG = 118; // -
    int DNEG = 119; // -
    int ISHL = 120; // -
    int LSHL = 121; // -
    int ISHR = 122; // -
    int LSHR = 123; // -
    int IUSHR = 124; // -
    int LUSHR = 125; // -
    int IAND = 126; // -
    int LAND = 127; // -
    int IOR = 128; // -
    int LOR = 129; // -
    int IXOR = 130; // -
    int LXOR = 131; // -
    int IINC = 132; // visitIincInsn
    int I2L = 133; // visitInsn
    int I2F = 134; // -
    int I2D = 135; // -
    int L2I = 136; // -
    int L2F = 137; // -
    int L2D = 138; // -
    int F2I = 139; // -
    int F2L = 140; // -
    int F2D = 141; // -
    int D2I = 142; // -
    int D2L = 143; // -
    int D2F = 144; // -
    int I2B = 145; // -
    int I2C = 146; // -
    int I2S = 147; // -
    int LCMP = 148; // -
    int FCMPL = 149; // -
    int FCMPG = 150; // -
    int DCMPL = 151; // -
    int DCMPG = 152; // -
    int IFEQ = 153; // visitJumpInsn
    int IFNE = 154; // -
    int IFLT = 155; // -
    int IFGE = 156; // -
    int IFGT = 157; // -
    int IFLE = 158; // -
    int IF_ICMPEQ = 159; // -
    int IF_ICMPNE = 160; // -
    int IF_ICMPLT = 161; // -
    int IF_ICMPGE = 162; // -
    int IF_ICMPGT = 163; // -
    int IF_ICMPLE = 164; // -
    int IF_ACMPEQ = 165; // -
    int IF_ACMPNE = 166; // -
    int GOTO = 167; // -
    int JSR = 168; // -
    int RET = 169; // visitVarInsn
    int TABLESWITCH = 170; // visiTableSwitchInsn
    int LOOKUPSWITCH = 171; // visitLookupSwitch
    int IRETURN = 172; // visitInsn
    int LRETURN = 173; // -
    int FRETURN = 174; // -
    int DRETURN = 175; // -
    int ARETURN = 176; // -
    int RETURN = 177; // -
    int GETSTATIC = 178; // visitFieldInsn
    int PUTSTATIC = 179; // -
    int GETFIELD = 180; // -
    int PUTFIELD = 181; // -
    int INVOKEVIRTUAL = 182; // visitMethodInsn
    int INVOKESPECIAL = 183; // -
    int INVOKESTATIC = 184; // -
    int INVOKEINTERFACE = 185; // -
    int INVOKEDYNAMIC = 186; // visitInvokeDynamicInsn
    int NEW = 187; // visitTypeInsn
    int NEWARRAY = 188; // visitIntInsn
    int ANEWARRAY = 189; // visitTypeInsn
    int ARRAYLENGTH = 190; // visitInsn
    int ATHROW = 191; // -
    int CHECKCAST = 192; // visitTypeInsn
    int INSTANCEOF = 193; // -
    int MONITORENTER = 194; // visitInsn
    int MONITOREXIT = 195; // -
    // int WIDE = 196; // NOT VISITED
    int MULTIANEWARRAY = 197; // visitMultiANewArrayInsn
    int IFNULL = 198; // visitJumpInsn
    int IFNONNULL = 199; // -
    // int GOTO_W = 200; // -
    // int JSR_W = 201; // -
}

3 asm中使用ClassReader读取.class信息

3.1 ClassReader提供四个构造方法用来加载class

public ClassReader(final byte[] b)
public ClassReader(final InputStream is)
public ClassReader(final String name)
public ClassReader(final byte[] b, final int off, final int len)

3.2 读取BusIndex.class基本信息

  • 3.2.1 加载class

    ClassReader classReader = new ClassReader(BusIndex.class.getName());

  • 3.2.2 获取类名

    classReader.getClassName()

  • 3.2.3 获取父类名

    classReader.getSuperName()

  • 3.2.4 获取接口

    classReader.getInterfaces()

3.3 打印class基本信息

System.out.println(classReader.getClassName());
System.out.println(Arrays.toString(classReader.getInterfaces()));
System.out.println(classReader.getSuperName());

3.4 控制台输出结果

com/eventbus/gen/BusIndex
[]
com/a/a/c/a

3.5 使用ClassVisitor读取BusIndex.class详细信息

  • 3.5.1 ClassReader提供了 accept方法可以遍历class的具体信息,该方法有两个重载

    public void accept(final ClassVisitor classVisitor,final Attribute[] attrs, final int flags) public void accept(final ClassVisitor classVisitor,final int flags)

  • 3.5.2 其中参数ClassVisitor用来遍历class信息, flags用来设置遍历信息级别

  • 3.5.3 遍历class具体信息

    classReader.accept(new SimpleClassVisitor(), 0); static class SimpleClassVisitor extends ClassVisitor {

        public SimpleClassVisitor() {
            super(Opcodes.ASM6);
        }
    
        @Override
        public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
            super.visit(version, access, name, signature, superName, interfaces);
            System.out.println(Thread.currentThread().getStackTrace()[1].getMethodName()+", version:"+version+", access:"+access+", name:"+name+", signature:"+signature+", supperName:"+signature+", interfaces:"+ Arrays.toString(interfaces));
    
        }
    
        @Override
        public AnnotationVisitor visitAnnotation(String desc, boolean visible) {
            System.out.println(Thread.currentThread().getStackTrace()[1].getMethodName()+", desc:"+desc+", visible:"+visible);
    
            return super.visitAnnotation(desc, visible);
        }
    
        @Override
        public void visitAttribute(Attribute attr) {
            super.visitAttribute(attr);
            System.out.println(Thread.currentThread().getStackTrace()[1].getMethodName()+", attr:"+attr);
    
        }
    
        @Override
        public void visitEnd() {
            super.visitEnd();
            System.out.println(Thread.currentThread().getStackTrace()[1].getMethodName());
    
        }
    
        @Override
        public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) {
            System.out.println(Thread.currentThread().getStackTrace()[1].getMethodName()+", access:"+access+", name:"+name+", desc:"+desc+", signature:"+signature+", value:"+value);
    
            return super.visitField(access, name, desc, signature, value);
        }
    
        @Override
        public void visitInnerClass(String name, String outerName, String innerName, int access) {
            System.out.println(Thread.currentThread().getStackTrace()[1].getMethodName()+", name:"+name+", outerName:"+outerName+", innerName:"+innerName+", access:"+access);
    
            super.visitInnerClass(name, outerName, innerName, access);
        }
    
        @Override
        public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
            System.out.println(Thread.currentThread().getStackTrace()[1].getMethodName()+", access:"+access+", name:"+name+", desc:"+desc+", signature:"+signature+", exceptions:"+Arrays.toString(exceptions));
    
    
            return super.visitMethod(access, name, desc, signature, exceptions);
        }
    
        @Override
        public ModuleVisitor visitModule() {
            System.out.println(Thread.currentThread().getStackTrace()[1].getMethodName());
    
            return super.visitModule();
        }
    
        @Override
        public void visitOuterClass(String owner, String name, String desc) {
            System.out.println(Thread.currentThread().getStackTrace()[1].getMethodName()+", owner:"+owner+", name:"+name+", desc:"+desc);
    
            super.visitOuterClass(owner, name, desc);
        }
    
        @Override
        public void visitSource(String source, String debug) {
            System.out.println(Thread.currentThread().getStackTrace()[1].getMethodName()+", source:"+source+", debug:"+debug);
    
            super.visitSource(source, debug);
        }
    
        @Override
        public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) {
            System.out.println(Thread.currentThread().getStackTrace()[1].getMethodName()+", typeRef:"+typeRef+", typePath:"+typePath+", desc:"+desc+", visible:"+visible);
    
            return super.visitTypeAnnotation(typeRef, typePath, desc, visible);
        }
    }
    
  • 3.5.4 控制台输出结果

    visit, version:51, access:49, name:com/eventbus/gen/BusIndex, signature:null, supperName:null, interfaces:[] visitSource, source:SourceFile, debug:null visitInnerClass, name:com/eventbus/gen/d, outerName:null, innerName:null, access:0 visitInnerClass, name:com/eventbus/gen/c, outerName:null, innerName:null, access:0 visitInnerClass, name:com/eventbus/gen/b, outerName:null, innerName:null, access:0 visitInnerClass, name:com/eventbus/gen/a, outerName:null, innerName:null, access:0 visitInnerClass, name:com/sample/app/MainActivity$a, outerName:com/sample/app/MainActivity, innerName:a, access:9 visitMethod, access:1, name:, desc:()V, signature:null, exceptions:null visitMethod, access:1, name:generateSubscribeMethodIndex, desc:(Ljava/lang/Object;)Lcom/a/a/c/d;, signature:null, exceptions:null visitEnd

  • 3.5.5 从输入结果中可以看出

    • version:

    version:51 与反编译结果一致

    • flags:

    access:49 与反编译结果一致Opcodes.ACC_PUBLIC+Opcodes.ACC_FINAL+Opcodes.ACC_SUPER = 49

    • InnerClasses:

    visitInnerClass, name:com/eventbus/gen/d, outerName:null, innerName:null, access:0 visitInnerClass, name:com/eventbus/gen/c, outerName:null, innerName:null, access:0 visitInnerClass, name:com/eventbus/gen/b, outerName:null, innerName:null, access:0 visitInnerClass, name:com/eventbus/gen/a, outerName:null, innerName:null, access:0 visitInnerClass, name:com/sample/app/MainActivity$a, outerName:com/sample/app/MainActivity, innerName:a, access:9

    • method:

    visitMethod, access:1, name:, desc:()V, signature:null, exceptions:null visitMethod, access:1, name:generateSubscribeMethodIndex, desc:(Ljava/lang/Object;)Lcom/a/a/c/d;, signature:null, exceptions:null

3.6 使用MethodVisitor读取BusIndex.class中方法的详细信息

  • 3.6.1 ClassVisitor的visitMethod只能获取方法的基本信息,如果要获取方法的详细信息就必须在visitMethod返回一个自定义的MethodVisitor。

    static class SimpleMethodVisitor extends MethodVisitor{ public SimpleMethodVisitor(MethodVisitor mv) { super(Opcodes.ASM6, mv); } @Override public AnnotationVisitor visitAnnotation(String desc, boolean visible) { System.out.println(Thread.currentThread().getStackTrace()[1].getMethodName()+", desc:"+desc+", visible:"+visible); return super.visitAnnotation(desc, visible); } @Override public AnnotationVisitor visitAnnotationDefault() { System.out.println(Thread.currentThread().getStackTrace()[1].getMethodName()); return super.visitAnnotationDefault(); } @Override public void visitAttribute(Attribute attr) { super.visitAttribute(attr); System.out.println(Thread.currentThread().getStackTrace()[1].getMethodName()+", attr:"+attr); } @Override public void visitCode() { super.visitCode(); System.out.println("visitor method begin."); System.out.println(Thread.currentThread().getStackTrace()[1].getMethodName()); } @Override public void visitEnd() { super.visitEnd(); System.out.println(Thread.currentThread().getStackTrace()[1].getMethodName()); System.out.println("visitor method ended."); } @Override public void visitFieldInsn(int opcode, String owner, String name, String desc) { super.visitFieldInsn(opcode, owner, name, desc); System.out.println(Thread.currentThread().getStackTrace()[1].getMethodName()+", opcode:"+Optcodes.options.get(opcode)+", owner:"+owner+", name:"+name+", desc:"+desc); } @Override public void visitFrame(int type, int nLocal, Object[] local, int nStack, Object[] stack) { super.visitFrame(type, nLocal, local, nStack, stack); } @Override public void visitIincInsn(int var, int increment) { super.visitIincInsn(var, increment); System.out.println(Thread.currentThread().getStackTrace()[1].getMethodName()+", var:"+var+", increment:"+increment); } @Override public void visitInsn(int opcode) { super.visitInsn(opcode); System.out.println(Thread.currentThread().getStackTrace()[1].getMethodName()+", opcode:"+Optcodes.options.get(opcode)); } @Override public AnnotationVisitor visitInsnAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) { System.out.println(Thread.currentThread().getStackTrace()[1].getMethodName()+", typeRef:"+typeRef+", typePath:"+typePath+", desc:"+desc+", visible:"+visible); return super.visitInsnAnnotation(typeRef, typePath, desc, visible); } @Override public void visitIntInsn(int opcode, int operand) { super.visitIntInsn(opcode, operand); System.out.println(Thread.currentThread().getStackTrace()[1].getMethodName()+", opcode:"+Optcodes.options.get(opcode)+", operand:"+operand); } @Override public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) { super.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs); } @Override public void visitJumpInsn(int opcode, Label label) { super.visitJumpInsn(opcode, label); System.out.println(Thread.currentThread().getStackTrace()[1].getMethodName()+", opcode:"+Optcodes.options.get(opcode)+", label:"+label); } @Override public void visitLabel(Label label) { super.visitLabel(label); System.out.println(Thread.currentThread().getStackTrace()[1].getMethodName()+", label:"+label); } @Override public void visitLdcInsn(Object cst) { super.visitLdcInsn(cst); System.out.println(Thread.currentThread().getStackTrace()[1].getMethodName()+", cst:"+cst); } @Override public void visitLineNumber(int line, Label start) { super.visitLineNumber(line, start); System.out.println(Thread.currentThread().getStackTrace()[1].getMethodName()+", line:"+line+", start label:"+line); } @Override public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) { super.visitLocalVariable(name, desc, signature, start, end, index); System.out.println(Thread.currentThread().getStackTrace()[1].getMethodName()+", name:"+name+", desc:"+desc+", signature:"+signature); } @Override public AnnotationVisitor visitLocalVariableAnnotation(int typeRef, TypePath typePath, Label[] start, Label[] end, int[] index, String desc, boolean visible) { return super.visitLocalVariableAnnotation(typeRef, typePath, start, end, index, desc, visible); } @Override public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) { super.visitLookupSwitchInsn(dflt, keys, labels); } @Override public void visitMaxs(int maxStack, int maxLocals) { super.visitMaxs(maxStack, maxLocals); } @Override public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { super.visitMethodInsn(opcode, owner, name, desc, itf); System.out.println(Thread.currentThread().getStackTrace()[1].getMethodName()+", opcode:"+Optcodes.options.get(opcode)+", owner:"+owner+", name:"+name+", desc:"+desc); } @Override public void visitMultiANewArrayInsn(String desc, int dims) { super.visitMultiANewArrayInsn(desc, dims); } @Override public void visitParameter(String name, int access) { super.visitParameter(name, access); System.out.println(Thread.currentThread().getStackTrace()[1].getMethodName()+", name:"+name+", access:"+access); } @Override public AnnotationVisitor visitParameterAnnotation(int parameter, String desc, boolean visible) { return super.visitParameterAnnotation(parameter, desc, visible); } @Override public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) { super.visitTableSwitchInsn(min, max, dflt, labels); } @Override public AnnotationVisitor visitTryCatchAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) { return super.visitTryCatchAnnotation(typeRef, typePath, desc, visible); } @Override public void visitTryCatchBlock(Label start, Label end, Label handler, String type) { super.visitTryCatchBlock(start, end, handler, type); } @Override public AnnotationVisitor visitTypeAnnotation(int typeRef, TypePath typePath, String desc, boolean visible) { return super.visitTypeAnnotation(typeRef, typePath, desc, visible); } @Override public void visitTypeInsn(int opcode, String type) { super.visitTypeInsn(opcode, type); System.out.println(Thread.currentThread().getStackTrace()[1].getMethodName()+", opcode:"+ Optcodes.options.get(opcode)+", type:"+type); } @Override public void visitVarInsn(int opcode, int var) { super.visitVarInsn(opcode, var); System.out.println(Thread.currentThread().getStackTrace()[1].getMethodName()+", opcode:"+ Optcodes.options.get(opcode)+",var:"+var); } }

  • 3.6.2 在ClassVisitor的visitMethod方法中使用SimpleMethodVisitor获取generateSubscribeMethodIndex方法的具体信息

    @Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { MethodVisitor methodVisitor = super.visitMethod(access, name, desc, signature, exceptions); System.out.println(Thread.currentThread().getStackTrace()[1].getMethodName()+", access:"+access+", name:"+name+", desc:"+desc+", signature:"+signature+", exceptions:"+Arrays.toString(exceptions)); if(name.equals("generateSubscribeMethodIndex")){ return new SimpleMethodVisitor(methodVisitor); } return methodVisitor; }

  • 3.6.3 输出结果

    visit, version:51, access:49, name:com/eventbus/gen/BusIndex, signature:null, supperName:null, interfaces:[] visitSource, source:SourceFile, debug:null visitInnerClass, name:com/eventbus/gen/d, outerName:null, innerName:null, access:0 visitInnerClass, name:com/eventbus/gen/c, outerName:null, innerName:null, access:0 visitInnerClass, name:com/eventbus/gen/b, outerName:null, innerName:null, access:0 visitInnerClass, name:com/eventbus/gen/a, outerName:null, innerName:null, access:0 visitInnerClass, name:com/sample/app/MainActivity$a, outerName:com/sample/app/MainActivity, innerName:a, access:9 visitMethod, access:1, name:, desc:()V, signature:null, exceptions:null visitMethod, access:1, name:generateSubscribeMethodIndex, desc:(Ljava/lang/Object;)Lcom/a/a/c/d;, signature:null, exceptions:null visitor method begin. visitCode visitLabel, label:L1072591677 visitLineNumber, line:18, start label:18 visitTypeInsn, opcode:NEW, type:com/a/a/c/d visitInsn, opcode:DUP visitMethodInsn, opcode:INVOKESPECIAL, owner:com/a/a/c/d, name:, desc:()V visitVarInsn, opcode:ASTORE,var:2 visitLabel, label:L918221580 visitLineNumber, line:19, start label:19 visitVarInsn, opcode:ALOAD,var:1 visitMethodInsn, opcode:INVOKEVIRTUAL, owner:java/lang/Object, name:getClass, desc:()Ljava/lang/Class; visitVarInsn, opcode:ASTORE,var:3 visitLabel, label:L2055281021 visitLineNumber, line:20, start label:20 visitInsn, opcode:ACONST_NULL visitVarInsn, opcode:ASTORE,var:4 visitLabel, label:L1554547125 visitLineNumber, line:21, start label:21 visitInsn, opcode:ACONST_NULL visitVarInsn, opcode:ASTORE,var:5 visitLabel, label:L617901222 visitLineNumber, line:22, start label:22 visitInsn, opcode:ACONST_NULL visitVarInsn, opcode:ASTORE,var:6 visitLabel, label:L1159190947 visitLineNumber, line:23, start label:23 visitVarInsn, opcode:ALOAD,var:3 visitLdcInsn, cst:Lcom/sample/app/MainActivity; visitJumpInsn, opcode:IF_ACMPNE, label:L681842940 visitLabel, label:L1392838282 visitLineNumber, line:24, start label:24 visitLdcInsn, cst:Lcom/sample/app/MainActivity$a; visitVarInsn, opcode:ASTORE,var:4 visitLabel, label:L523429237 visitLineNumber, line:25, start label:25 visitLdcInsn, cst:Lcom/a/a/d/a; visitVarInsn, opcode:ASTORE,var:5 visitLabel, label:L664740647 visitLineNumber, line:26, start label:26 visitLdcInsn, cst:showMessage visitVarInsn, opcode:ASTORE,var:6 visitLabel, label:L804564176 visitLineNumber, line:27, start label:27 visitVarInsn, opcode:ALOAD,var:2 visitVarInsn, opcode:ALOAD,var:6 visitVarInsn, opcode:ALOAD,var:4 visitVarInsn, opcode:ALOAD,var:5 visitTypeInsn, opcode:NEW, type:com/eventbus/gen/a visitInsn, opcode:DUP visitVarInsn, opcode:ALOAD,var:0 visitVarInsn, opcode:ALOAD,var:1 visitVarInsn, opcode:ALOAD,var:6 visitVarInsn, opcode:ALOAD,var:4 visitVarInsn, opcode:ALOAD,var:5 visitMethodInsn, opcode:INVOKESPECIAL, owner:com/eventbus/gen/a, name:, desc:(Lcom/eventbus/gen/BusIndex;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/Class;)V visitMethodInsn, opcode:INVOKEVIRTUAL, owner:com/a/a/c/d, name:a, desc:(Ljava/lang/String;Ljava/lang/Class;Ljava/lang/Class;Lcom/a/a/b/a;)V visitLabel, label:L1421795058 visitLineNumber, line:33, start label:33 visitLdcInsn, cst:Lcom/sample/app/MainActivity$a; visitVarInsn, opcode:ASTORE,var:4 visitLabel, label:L1555009629 visitLineNumber, line:34, start label:34 visitLdcInsn, cst:Lcom/a/a/d/a; visitVarInsn, opcode:ASTORE,var:5 visitLabel, label:L41359092 visitLineNumber, line:35, start label:35 visitLdcInsn, cst:showMessagedd visitVarInsn, opcode:ASTORE,var:6 visitLabel, label:L149928006 visitLineNumber, line:36, start label:36 visitVarInsn, opcode:ALOAD,var:2 visitVarInsn, opcode:ALOAD,var:6 visitVarInsn, opcode:ALOAD,var:4 visitVarInsn, opcode:ALOAD,var:5 visitTypeInsn, opcode:NEW, type:com/eventbus/gen/b visitInsn, opcode:DUP visitVarInsn, opcode:ALOAD,var:0 visitVarInsn, opcode:ALOAD,var:1 visitVarInsn, opcode:ALOAD,var:6 visitVarInsn, opcode:ALOAD,var:4 visitVarInsn, opcode:ALOAD,var:5 visitMethodInsn, opcode:INVOKESPECIAL, owner:com/eventbus/gen/b, name:, desc:(Lcom/eventbus/gen/BusIndex;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/Class;)V visitMethodInsn, opcode:INVOKEVIRTUAL, owner:com/a/a/c/d, name:a, desc:(Ljava/lang/String;Ljava/lang/Class;Ljava/lang/Class;Lcom/a/a/b/a;)V visitLabel, label:L713338599 visitLineNumber, line:42, start label:42 visitVarInsn, opcode:ALOAD,var:2 visitInsn, opcode:ARETURN visitLabel, label:L681842940 visitLineNumber, line:44, start label:44 visitVarInsn, opcode:ALOAD,var:3 visitLdcInsn, cst:Lcom/sample/app/Main2Activity; visitJumpInsn, opcode:IF_ACMPNE, label:L168423058 visitLabel, label:L821270929 visitLineNumber, line:45, start label:45 visitLdcInsn, cst:Lcom/sample/app/MainActivity$a; visitVarInsn, opcode:ASTORE,var:4 visitLabel, label:L1160460865 visitLineNumber, line:46, start label:46 visitLdcInsn, cst:Lcom/a/a/d/a; visitVarInsn, opcode:ASTORE,var:5 visitLabel, label:L1247233941 visitLineNumber, line:47, start label:47 visitLdcInsn, cst:showMessage visitVarInsn, opcode:ASTORE,var:6 visitLabel, label:L258952499 visitLineNumber, line:48, start label:48 visitVarInsn, opcode:ALOAD,var:2 visitVarInsn, opcode:ALOAD,var:6 visitVarInsn, opcode:ALOAD,var:4 visitVarInsn, opcode:ALOAD,var:5 visitTypeInsn, opcode:NEW, type:com/eventbus/gen/c visitInsn, opcode:DUP visitVarInsn, opcode:ALOAD,var:0 visitVarInsn, opcode:ALOAD,var:1 visitVarInsn, opcode:ALOAD,var:6 visitVarInsn, opcode:ALOAD,var:4 visitVarInsn, opcode:ALOAD,var:5 visitMethodInsn, opcode:INVOKESPECIAL, owner:com/eventbus/gen/c, name:, desc:(Lcom/eventbus/gen/BusIndex;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/Class;)V visitMethodInsn, opcode:INVOKEVIRTUAL, owner:com/a/a/c/d, name:a, desc:(Ljava/lang/String;Ljava/lang/Class;Ljava/lang/Class;Lcom/a/a/b/a;)V visitLabel, label:L603742814 visitLineNumber, line:54, start label:54 visitLdcInsn, cst:Lcom/sample/app/MainActivity$a; visitVarInsn, opcode:ASTORE,var:4 visitLabel, label:L1067040082 visitLineNumber, line:55, start label:55 visitLdcInsn, cst:Lcom/a/a/d/a; visitVarInsn, opcode:ASTORE,var:5 visitLabel, label:L1325547227 visitLineNumber, line:56, start label:56 visitLdcInsn, cst:showMessagedd visitVarInsn, opcode:ASTORE,var:6 visitLabel, label:L980546781 visitLineNumber, line:57, start label:57 visitVarInsn, opcode:ALOAD,var:2 visitVarInsn, opcode:ALOAD,var:6 visitVarInsn, opcode:ALOAD,var:4 visitVarInsn, opcode:ALOAD,var:5 visitTypeInsn, opcode:NEW, type:com/eventbus/gen/d visitInsn, opcode:DUP visitVarInsn, opcode:ALOAD,var:0 visitVarInsn, opcode:ALOAD,var:1 visitVarInsn, opcode:ALOAD,var:6 visitVarInsn, opcode:ALOAD,var:4 visitVarInsn, opcode:ALOAD,var:5 visitMethodInsn, opcode:INVOKESPECIAL, owner:com/eventbus/gen/d, name:, desc:(Lcom/eventbus/gen/BusIndex;Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Class;Ljava/lang/Class;)V visitMethodInsn, opcode:INVOKEVIRTUAL, owner:com/a/a/c/d, name:a, desc:(Ljava/lang/String;Ljava/lang/Class;Ljava/lang/Class;Lcom/a/a/b/a;)V visitLabel, label:L2061475679 visitLineNumber, line:63, start label:63 visitVarInsn, opcode:ALOAD,var:2 visitInsn, opcode:ARETURN visitLabel, label:L168423058 visitLineNumber, line:65, start label:65 visitVarInsn, opcode:ALOAD,var:2 visitInsn, opcode:ARETURN visitEnd visitor method ended. visitEnd

  • 3.6.4 从结果中可以看出visitor method begin与visitor method ended之间输出的就是generateSubscribeMethodIndex的具体信息

3.7 同理如果要读取字段,枚举,变量等的具体信息在相应的方法中返回自定义的visitor即可

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
Java获得今日零时零分零秒的时间(Date型)
publicDatezeroTime()throwsParseException{    DatetimenewDate();    SimpleDateFormatsimpnewSimpleDateFormat("yyyyMMdd00:00:00");    SimpleDateFormatsimp2newS
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
9个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这