版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_36367789/article/details/81605625
  • class文件结构

    • 无符号数
  • Class文件设计理念和意义
  • 1. 魔数magic
    • 证明magic作用
  • minor_version、major_version
  • 2. constant_pool_count
  • 3. constant_pool[]常量池
      • 3.1 CONSTANT_Class_info结构
      • 3.2 CONSTANT_Fieldref_info, CONSTANT_Methodref_info和CONSTANT_InterfaceMethodref_info结构
    • 3.3 CONSTANT_String_info结构
      • 3.4CONSTANT_Integer_info和CONSTANT_Float_info结构
      • 3.5CONSTANT_Long_info和CONSTANT_Double_info结构
      • 3.6 CONSTANT_NameAndType_info结构
      • 3.7 CONSTANT_Utf8_info结构
      • 3.8 CONSTANT_MethodHandle_info结构
      • 3.9 CONSTANT_MethodType_info结构
      • 3.10 CONSTANT_InvokeDynamic_info结构
  • 4. access_flags:访问标志
  • 5. this_class:类索引
  • 6. super_class:父类索引
  • 7. interfaces_count:接口计数器
  • 8. interfaces[]:接口表
  • 9. fields_count:字段计数器
  • 10. fields[]:字段表
  • 11. methods_count:方法计数器
  • 12. methods[]:方法表
  • 13. attributes_count:属性计数器
  • 14. attributes[]:属性表
    • 14.1 ConstantValue属性
    • 14.2 Code属性
    • 14.3 StackMapTable属性
  • 字节码指令
    • 常量入栈指令
    • 局部变量值转载到栈中指令
    • 将栈顶值保存到局部变量中指令
    • wide指令
    • 通用(无类型)栈操作指令
    • 类型转换指令
    • 整数运算
    • 浮点运算
    • 逻辑运算——移位运算
    • 逻辑运算——按位布尔运算
    • 控制流指令——条件跳转指令
    • 控制流指令——比较指令
    • 控制流指令——无条件跳转指令
    • 控制流指令——表跳转指令
    • 控制流指令——异常和finally
    • 对象操作指令
    • 数组操作指令
    • 方法调用指令
    • 方法返回指令
    • 线程同步指令
  • 一个简单的demo分析
    • Test.java
    • javap -v Test.class

class文件结构

Class文件存储的内容称为字节码(ByteCode),包含了JVM指令集和符号表以及若干其他辅助信息。

class文件是一组以8位字节为基础单位的二进制流,各个数据项目严格按照顺序紧凑的排列在Class文件中,中间没有添加任何分隔符,整个Class文件中存储的内容几乎全部是程序运行的必要的数据,没有空隙存在。

当遇到8位字节以上的空间的数据项时,则会按照高位在前的方式分割成若干个8位字节进行存储。

Class文件中有两种数据类型,分别是无符号数和表。

无符号数

无符号数属于基本的数据类型,以u1、u2、u4、u8来表示一个字节、两个字节…的无符号数;无符号数用来描述数字、索引引用、数量值或UTF-8编码构成的字符串值。

表是由多个无符号数或其他表作为数据项构成的复合数据类型,一般以”_info”结尾,用来描述class文件的数据结构。

特点:节省存储空间,提高处理性能

ClassFile { u4 magic; u2 minor_version; u2 major_version; u2 constant_pool_count; cp_info constant_pool[constant_pool_count-1]; u2 access_flags; u2 this_class; u2 super_class; u2 interfaces_count; u2 interfaces[interfaces_count]; u2 fields_count; field_info fields[fields_count]; u2 methods_count; method_info methods[methods_count]; u2 attributes_count; attribute_info attributes[attributes_count];
}
  • 魔数
  • Class文件版本
  • 常量池
  • 访问标志
  • 类索引,父类索引,接口索引集合
  • 字段表集合
  • 方法表集合
  • 属性表集合

u2表示无符号数2个字节
u4表示无符号数4个字节

Class文件设计理念和意义

1. 魔数magic

魔数的唯一作用是确定这个文件是否为一个能被虚拟机所接受的Class文件。魔数值固定为0xCAFEBABE,不会改变。

证明magic作用

创建一个class文件 magic.class ,内容是magic test,直接运行java magic操作:

84407@FantJ MINGW64 ~/Desktop
$ java magictest
▒▒▒▒: ▒▒▒▒▒▒▒▒ magictest ʱ▒▒▒▒ LinkageErrorjava.lang.ClassFormatError: Incompatible magic value 1886741100 in class file magictest

报错意思是:magic矛盾,然后给了个magic value的十进制数,那么可以识别的magic十进制应该是多少呢。


应该是3405691582

那么,然后我用javac编译的正常java文件生成class文件,用binary viewer 查看:

minor_version、major_version

魔数往后后面四位:表示字节码版本,分别表示Class文件的副、主版本。当今用的最广的几个版本:
jdk1.8:52
jdk1.7:51
jdk1.6:50


对应版本号是52,是jdk1.8

版本向下兼容

2. constant_pool_count

常量池计数器,值等于constant_pool表中的成员数加1,占用两个字节

3. constant_pool[]常量池

Java虚拟机指令执行时依赖常量池(constant_pool)表中的符号信息。

所有的常量池项都具有如下通用格式:

cp_info {u1 tag; u1 info[];
}

info[]项的内容tag由的类型所决定。tag有效的类型和对应的取值在下表列出

常量类型
CONSTANT_Class 7
CONSTANT_Fieldref 9
CONSTANT_Methodref 10
CONSTANT_InterfaceMethodref 11
CONSTANT_String 8
CONSTANT_Integer 3
CONSTANT_Float 4
CONSTANT_Long 5
CONSTANT_Double 6
CONSTANT_NameAndType 12
CONSTANT_Utf8 1
CONSTANT_MethodHandle 15
CONSTANT_MethodType 16
CONSTANT_InvokeDynamic 18
3.1 CONSTANT_Class_info结构

表示类或接口

CONSTANT_Class_info {u1 tag; u2 name_index;
}

name_index必须是对常量池的一个有效索引

3.2 CONSTANT_Fieldref_info, CONSTANT_Methodref_info和CONSTANT_InterfaceMethodref_info结构

字段:

CONSTANT_Fieldref_info {u1 tag; u2 class_index; u2 name_and_type_index;
}

方法:

CONSTANT_Methodref_info { u1 tag; u2 class_index; u2 name_and_type_index;
}

接口方法:

CONSTANT_InterfaceMethodref_info {u1 tag; u2 class_index; u2 name_and_type_index;
}

class_index必须是对常量池的有效索引,常量池在该索引处的项必须是CONSTANT_Class_info结构,表示一个类或接口,当前字段或方法是这个类或接口的成员。

CONSTANT_Methodref_info结构的class_index项的类型必须是类(不能是接口)。CONSTANT_InterfaceMethodref_info结构的class_index项的类型必须是接口(不能是类)。CONSTANT_Fieldref_info结构的class_index项的类型既可以是类也可以是接口。

name_and_type_index必须是对常量池的有效索引,表示当前字段或方法的名字和描述符。
在一个CONSTANT_Fieldref_info结构中,给定的描述符必须是字段描述符。而CONSTANT_Methodref_infoCONSTANT_InterfaceMethodref_info中给定的描述符必须是方法描述符。

3.3 CONSTANT_String_info结构

用来表示String的结构

CONSTANT_String_info {u1 tag;u2 string_index;
}

string_index必须是对常量池的有效索引,常量池在该索引处的项必须是CONSTANT_Utf8_info
结构,表示一组Unicode码点序列,这组Unicode码点序列最终会被初始化为一个String对象。

3.4CONSTANT_Integer_info和CONSTANT_Float_info结构

表示4字节(int和float)的数值常量:

CONSTANT_Integer_info {u1 tag; u4 bytes;
}
CONSTANT_Float_info { u1 tag; u4 bytes;
}
3.5CONSTANT_Long_info和CONSTANT_Double_info结构

表示8字节(long和double)的数值常量

CONSTANT_Long_info {u1 tag; u4 high_bytes; u4 low_bytes;
} CONSTANT_Double_info { u1 tag; u4 high_bytes; u4 low_bytes;
}
3.6 CONSTANT_NameAndType_info结构

表示字段或方法,但是和前面介绍的3个结构不同,CONSTANT_NameAndType_info结构没有标识出它所属的类或接口

CONSTANT_NameAndType_info { u1 tag; u2 name_index; u2 descriptor_index;
}

name_index项的值必须是对常量池的有效索引,常量池在该索引处的项必须是CONSTANT_Utf8_info结构,这个结构要么表示特殊的方法名,要么表示一个有效的字段或方法的非限定名(Unqualified Name)。

descriptor_index项的值必须是对常量池的有效索引,常量池在该索引处的项必须是CONSTANT_Utf8_info结构,这个结构表示一个有效的字段描述符或方法描述符。

3.7 CONSTANT_Utf8_info结构

用于表示字符串常量的值

CONSTANT_Utf8_info {u1 tag; u2 length; u1 bytes[length];
}

CONSTANT_Utf8_info结构中的内容是以length属性确定长度的

3.8 CONSTANT_MethodHandle_info结构

表示方法句柄

CONSTANT_MethodHandle_info {u1 tag;u1 reference_kind;u2 reference_index;
}

reference_kind项的值必须在1至9之间(包括1和9),它决定了方法句柄的类型。
1. 如果reference_kind项的值为1(REF_getField)、2(REF_getStatic)、3(REF_putField)或4(REF_putStatic),那么常量池在reference_index索引处的项必须是CONSTANT_Fieldref_info结构,表示由一个字段创建的方法句柄。
2. 如果reference_kind项的值是5(REF_invokeVirtual)、6(REF_invokeStatic)、7(REF_invokeSpecial)或8(REF_newInvokeSpecial),那么常量池在reference_index索引处的项必须是CONSTANT_Methodref_info结构,表示由类的方法或构造函数创建的方法句柄。
3. 如果reference_kind项的值是9(REF_invokeInterface),那么常量池在reference_index索引处的项必须是CONSTANT_InterfaceMethodref_info结构,表示由接口方法创建的方法句柄。
4. 如果reference_kind项的值是5(REF_invokeVirtual)、6(REF_invokeStatic)、7(REF_invokeSpecial)或9(REF_invokeInterface),那么方法句柄对应的方法不能为实例初始化()方法或类初始化方法()。
5. 如果reference_kind项的值是8(REF_newInvokeSpecial),那么方法句柄对应的方法必须为实例初始化()方法。

3.9 CONSTANT_MethodType_info结构

表示方法类型

CONSTANT_MethodType_info { u1 tag; u2 descriptor_index;
}
3.10 CONSTANT_InvokeDynamic_info结构

表示invokedynamic指令所使用到的引导方法(Bootstrap Method)、引导方法使用到动态调用名称(Dynamic Invocation Name)、参数和请求返回类型、以及可以选择性的附加被称为静态参数(Static Arguments)的常量序列。

CONSTANT_InvokeDynamic_info { u1 tag; u2 bootstrap_method_attr_index; u2 name_and_type_index;
}

bootstrap_method_attr_index项的值必须是对当前Class文件中引导方法表的bootstrap_methods[]数组的有效索引。

name_and_type_index项的值必须是对当前常量池的有效索引,常量池在该索引处的项必须是CONSTANT_NameAndType_info结构,表示方法名和方法描述符。

4. access_flags:访问标志

访问标志,access_flags是一种掩码标志,用于表示某个类或者接口的访问权限及基础属性。access_flags的取值范围和相应含义见下表。

标记名 含义
ACC_PUBLIC 0x0001 可以被包的类外访问。
ACC_FINAL 0x0010 不允许有子类。
ACC_SUPER 0x0020 当用到invokespecial指令时,需要特殊处理的父类方法。
ACC_INTERFACE 0x0200 标识定义的是接口而不是类。
ACC_ABSTRACT 0x0400 不能被实例化。
ACC_SYNTHETIC 0x1000 标识并非Java源码生成的代码。
ACC_ANNOTATION 0x2000 标识注解类型
ACC_ENUM 0x4000 标识枚举类型

5. this_class:类索引

this_class的值必须是对constant_pool表中项目的一个有效索引值。

是一个对constant_pool表中项目的一个有效索引值,表示指向常量池的第几个位置。

6. super_class:父类索引

表示这个Class文件所定义的类的直接父类,如果Class文件的super_class的值为0,那这个Class文件只可能是定义的是java.lang.Object类,只有它是唯一没有父类的类

是一个对constant_pool表中项目的一个有效索引值,表示指向常量池的第几个位置。

7. interfaces_count:接口计数器

表示有这个类有几个接口。

8. interfaces[]:接口表

成员所表示的接口顺序和对应的源代码中给定的接口顺序(从左至右)一样,即interfaces[0]对应的是源代码中最左边的接口。

是一个对constant_pool表中项目的一个有效索引值,表示指向常量池的第几个位置。

表示当前类或接口的直接父接口数量

9. fields_count:字段计数器

表示当前Class文件fields[]数组的成员个数

10. fields[]:字段表

每个成员都必须是一个fields_info结构的数据项,描述当前类或接口声明的所有字段,但不包括从父类或父接口继承的部分。

用于表示当前类或接口中某个字段的完整描述

field_info {u2 access_flags; u2 name_index;      //对常量池的一个有效索引u2 descriptor_index;     //对常量池的一个有效索引u2 attributes_count;     //当前字段的附加属性的数量attribute_info attributes[attributes_count];
}

access_flags项的值是用于定义字段被访问权限和基础属性的掩码标志。access_flags的取值范围和相应含义见下表所示:

标记名 说明
ACC_PUBLIC 0x0001 public,表示字段可以从任何包访问。
ACC_PRIVATE 0x0002 private,表示字段仅能该类自身调用。
ACC_PROTECTED 0x0004 protected,表示字段可以被子类调用。
ACC_STATIC 0x0008 static,表示静态字段。
ACC_FINAL 0x0010 final,表示字段定义后值无法修改。
ACC_VOLATILE 0x0040 volatile,表示字段是易变的。
ACC_TRANSIENT 0x0080 transient,表示字段不会被序列化。
ACC_SYNTHETIC 0x1000 表示字段由编译器自动产生。
ACC_ENUM 0x4000 enum,表示字段为枚举类型。

attributes表的每一个成员的值必须是attribute结构,一个字段可以有任意个关联属性。

11. methods_count:方法计数器

methods_count的值表示当前Class文件methods[]数组的成员个数,Methods[]数组中每一项都是一个method_info结构的数据项。

12. methods[]:方法表

method_info结构可以表示类和接口中定义的所有方法,包括实例方法、类方法、实例初始化方法方法和类或接口初始化方法方法。methods[]数组只描述当前类或接口中声明的方法,不包括从父类或父接口继承的方法。

methods[]数组中的每个成员都必须是一个method_info结构的数据项,用于表示当前类或接口中某个方法的完整描述。

method_info { u2 access_flags; u2 name_index; u2 descriptor_index; u2 attributes_count; attribute_info attributes[attributes_count];
}

access_flags项的值是用于定义当前方法的访问权限和基本属性的掩码标志,access_flags的取值范围和相应含义见下表所示。

标记名 说明
ACC_PUBLIC 0x0001 public,方法可以从包外访问
ACC_PRIVATE 0x0002 private,方法只能本类中访问
ACC_PROTECTED 0x0004 protected,方法在自身和子类可以访问
ACC_STATIC 0x0008 static,静态方法
ACC_FINAL 0x0010 final,方法不能被重写(覆盖)
ACC_SYNCHRONIZED 0x0020 synchronized,方法由管程同步
ACC_BRIDGE 0x0040 bridge,方法由编译器产生
ACC_VARARGS 0x0080 表示方法带有变长参数
ACC_NATIVE 0x0100 native,方法引用非java语言的本地方法
ACC_ABSTRACT 0x0400 abstract,方法没有具体实现
ACC_STRICT 0x0800 strictfp,方法使用FP-strict浮点格式
ACC_SYNTHETIC 0x1000 方法在源文件中不出现,由编译器产生

name_indexdescriptor_index 两属性是对常量池的一个有效索引
attributes_count的项的值表示这个方法的附加属性的数量。
attributes 表的每一个成员的值必须是attribute结构,一个方法可以有任意个与之相关的属性。

13. attributes_count:属性计数器

attributes表中每一项都是一个attribute_info结构的数据项。

attributes_count的值表示当前Class文件attributes表的成员个数。

14. attributes[]:属性表

attributes表的每个项的值必须是attribute_info结构,在Class文件格式中的ClassFile结构、field_info结构,method_info结构和Code_attribute结构都有使用,所有属性的通用格式如下:

attribute_info {u2 attribute_name_index; u4 attribute_length; u1 info[attribute_length];
}

attribute_name_index必须是对当前Class文件的常量池的有效16位无符号索引。表示当前属性的名字。

attribute_length项的值给出了跟随其后的字节的长度,这个长度不包括attribute_name_indexattribute_name_index项的6个字节。

14.1 ConstantValue属性

ConstantValue属性是定长属性,位于field_info结构的属性表中。如果该字段为静态类型(即field_info结构的access_flags项设置了ACC_STATIC标志),则说明这个field_info结构表示的常量字段值将被分配为它的ConstantValue属性表示的值,这个过程也是类或接口申明的常量字段(Constant Field)初始化的一部分。这个过程发生在引用类或接口的类初始化方法执行之前。

ConstantValue_attribute { u2 attribute_name_index; u4 attribute_length; u2 constantvalue_index;
}

attribute_name_index项的值,必须是一个对常量池的有效索引。
attribute_length项的值固定为2。
constantvalue_index项的值,必须是一个对常量池的有效索引。

14.2 Code属性

Code属性是一个变长属性,位于method_info结构的属性表。一个Code属性只为唯一一个方法、实例类初始化方法或类初始化方法保存Java虚拟机指令及相关辅助信息。所有Java虚拟机实现都必须能够识别Code属性。如果方法被声明为native或者abstract类型,那么对应的method_info结构不能有明确的Code属性,其它情况下,method_info有必须有明确的Code属性。

Code_attribute {u2 attribute_name_index;u4 attribute_length; u2 max_stack;u2 max_locals;u4 code_length; u1 code[code_length]; u2 exception_table_length; {   u2 start_pc;u2 end_pc; u2 handler_pc; u2 catch_type; } exception_table[exception_table_length]; u2 attributes_count; attribute_info attributes[attributes_count];
}

attribute_name_index项的值必须是对常量池的有效索引
attribute_length项的值表示当前属性的长度,不包括开始的6个字节。
max_stack项的值给出了当前方法的操作数栈在运行执行的任何时间点的最大深度。
max_locals项的值给出了分配在当前方法引用的局部变量表中的局部变量个数,包括调用此方法时用于传递参数的局部变量。long和double型的局部变量的最大索引是max_locals-2,其它类型的局部变量的最大索引是max_locals-1.
code_length项给出了当前方法的code[]数组的字节数,code_length的值必须大于0,即code[]数组不能为空。
code[]数组给出了实现当前方法的Java虚拟机字节码。
exception_table_length项的值给出了exception_table[]数组的成员个数量。
exception_table[]数组的每个成员表示code[]数组中的一个异常处理器(Exception Handler)。exception_table[]数组中,异常处理器顺序是有意义的(不能随意更改)。
start_pcend_pc两项的值表明了异常处理器在code[]数组中的有效范围。
handler_pc项表示一个异常处理器的起点
如果catch_type项的值不为0,那么它必须是对常量池的一个有效索引
attributes_count项的值给出了Code属性中attributes表的成员个数。
属性表的每个成员的值必须是attribute结构。一个Code属性可以有任意数量的可选属性与之关联。

14.3 StackMapTable属性

StackMapTable属性是一个变长属性,位于Code属性的属性表中。这个属性会在虚拟机类加载的类型阶段被使用。

StackMapTable_attribute { u2 attribute_name_index;u4 attribute_length; u2 number_of_entries; stack_map_frame entries[number_of_entries];
}

attribute_name_index项的值必须是对常量池的有效索引
attribute_length项的值表示当前属性的长度,不包括开始的6个字节。
number_of_entries项的值给出了entries表中的成员数量。Entries表的每个成员是都是一个stack_map_frame结构的项。
entries表给出了当前方法所需的stack_map_frame结构。

…更多的属性就不在这一一贴了,太多了,需要的时候查官方文档即可:https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4

字节码指令

java虚拟机指令由一个字节长度的,代表某种特定操作含义的数字(称之为操作码),以及随后的代表此操作所需参数的操作数而构成。

操作码的长度为1个字节,所以最大只有256条

常量入栈指令

局部变量值转载到栈中指令

将栈顶值保存到局部变量中指令

wide指令

通用(无类型)栈操作指令

类型转换指令

整数运算

浮点运算

逻辑运算——移位运算

逻辑运算——按位布尔运算

控制流指令——条件跳转指令

控制流指令——比较指令

控制流指令——无条件跳转指令

控制流指令——表跳转指令

控制流指令——异常和finally

对象操作指令

数组操作指令

方法调用指令

方法返回指令

线程同步指令

指令参考:https://blog.csdn.net/web_code/article/details/12164733

一个简单的demo分析

Test.java

public class Test {public static void main(String[] args) {int a = 10;int b = 20;int c = a+b;System.out.println(c);}
}

javap -v Test.class

   #2 = Fieldref           #24.#25        // java/lang/System.out:Ljava/io/PrintStream;#3 = Methodref          #26.#27        // java/io/PrintStream.println:(I)Vpublic static void main(java.lang.String[]);descriptor: ([Ljava/lang/String;)Vflags: (0x0009) ACC_PUBLIC, ACC_STATICCode:stack=2, locals=4, args_size=10: bipush        10    //把10扩展成int入栈2: istore_1      //将栈顶int类型值保存到局部变量1中3: bipush        20     //把20扩展成int入栈5: istore_2     //将栈顶int类型值保存到局部变量2中6: iload_1      //从局部变量1中装载int类型值入栈  7: iload_2     //从局部变量2中装载int类型值入栈  8: iadd       // 将栈顶两int类型数相加,结果入栈。9: istore_3     //将栈顶int类型值保存到局部变量3中10: getstatic     #2                  // Field java/lang/System.out:Ljava/io/PrintStream;获取静态字段的值。#2表示常量池的索引13: iload_314: invokevirtual #3                  // Method java/io/PrintStream.println:(I)V 运行时方法绑定调用方法。17: return      //void函数返回。

Class文件结构amp;字节码指令相关推荐

  1. class 类文件结构与字节码指令

    JVM执行子系统 一.Class 类文件结构 1.Java跨平台的基础 各种不同平台的虚拟机与所有平台都统一使用的程序存储格式--字节码(ByteCode)是构成平台无关性的基石,也是语言无关性的基础 ...

  2. java虚拟机编译_[四] java虚拟机JVM编译器编译代码简介 字节码指令实例 代码到底编译成了什么形式...

    前言简介 前文已经对虚拟机进行过了简单的介绍,并且也对class文件结构,以及字节码指令进行了详尽的说明 想要了解JVM的运行机制,以及如何优化你的代码,你还需要了解一下,java编译器到底是如何编译 ...

  3. c++byte数组和文件的相互转换_5分钟系列之Java类文件结构(三、字节码指令简介)...

    字节码指令简介1字节码与数据类型2加载和存储指令3运算指令4类型转换指令5对象创建与访问指令6操作数栈管理指令7 控制转移指令8方法调用和返回指令9异常处理指令10同步指令公有设计和私有实现Class ...

  4. Java的Class类文件结构及基本字节码指令

    Class类文件的结构 概念:Class文件是一组以8位字节为基础单位的二进制流 按顺序整齐排列 没有任何分隔符,内容全部是运行时的必要数据,没有空隙存在 排序方式:高位在前 Big-Endian:最 ...

  5. jvm(6)-java类文件结构(字节码文件)

    [0]README 0.1)本文部分文字描述转自 "深入理解jvm",旨在学习类文件结构  的基础知识: 0.2)本文荔枝以及荔枝的分析均为原创: 0.3)下面的截图中有附注t*编 ...

  6. JVM学习-字节码指令

    目录 1.入门 2 javap 工具 3 图解方法执行流程 3.1.原始 java 代码 3.2.编译后的字节码文件 3.3.常量池载入运行时常量池 3.4.方法字节码载入方法区 3.5.main 线 ...

  7. Class文件结构和字节码指令集

    Class文件结构和字节码指令集 概述 字节码文件的跨平台性 Java 语言:跨平台的语言(write once, run anywhere) 当Java源代码成功编译成字节码之后,如果想在不同的平台 ...

  8. 字节码文件及字节码指令

    我记得开始学习Java的第一堂课时,我的大学老师是这样说的,Java号称是"一次编写,到处运行",为什么有底气这样说,是因为Java程序并不是直接运行在操作系统上的,它通过不同操作 ...

  9. 你还在为怎么查看字节码指令而担忧吗?

    来自:烟雨星空 前言 我们平时编码过程中,可能很少去查看 Java 文件编译后的字节码指令.但是,不管你是因为对技术非常热爱,喜欢刨根问底,还是想在别人面前装X .我认为,都非常有必要了解一下常见的字 ...

最新文章

  1. SAP PM 入门系列7 - 常用Function Modules
  2. Linux上Core Dump文件的形成和分析
  3. ecshop 详情页面获取商品销量和评论数
  4. Python numpy 提取矩阵的某一行或某一列
  5. 过滤器跟拦截器的区别
  6. asp.net网站中CrystalReport的简单应用
  7. python rgb 图像_在Python中查找RGB图像的互补图像
  8. jni c java互相调用_通过JNI实现Java和C++的相互调用
  9. 【Logstash】logstash 报错 logstash cannot write event to DLQ reached maxQueueSize of
  10. linux安装 grub失败,安装linux+windows的系统 如果grub引导失败的解决方法
  11. 软件体系架构课下作业01
  12. C++中的error C2662,const的this指针问题
  13. 话题热议:有没有能替代Excel的数据处理软件?
  14. java数据类型简介
  15. 【宏】解决vcard乱码批量导入outlook
  16. 华三防火墙h3cf100配置双宽带_华三防火墙H3 F100基本配置说明.doc
  17. OA系统的集成与整合:打破信息孤岛,实现企业信息化融会贯通
  18. 上海亚商投顾大盘回顾:两市成交仅5600亿元 创两年半以来新低
  19. camtasia studio2022汉化屏幕录屏录像
  20. 欢迎来到天蓝零度的官方微博发布平台

热门文章

  1. 2016 - 2 - 20 ARC知识总结(二 autorelease概念及实现)
  2. flask登录验证用ajax,基于 Ajax 请求的 Flask-Login 认证
  3. 天然气门站监控摄像头如何布置_监控摄像头布置原则
  4. 为什么用redis做缓存而不是mybatis自带的缓存_如何用Java设计一个本地缓存,涨姿势了...
  5. iic总线从机仲裁_I2C总线的仲裁问题
  6. 八皇后问题c语言循环,八皇后问题的12组解
  7. C++ 通讯录设计(一)
  8. 如何评价一个产品经理工作做的好坏?
  9. 2021中国实体零售数字化专题报告——便利店篇
  10. 2021中国低代码市场研究报告