HotSpot虚拟机之Class文件及字节码指令

本文围绕Java编程展开,介绍了javac编译过程,包括准备和三个处理阶段,还提及语法糖。详细阐述了Class文件,涵盖文件格式、常量池项目和属性类型,给出实例并通过javap分析。此外,说明了字节码指令的组成和分类。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、javac编译

1. 编译过程

2. 语法糖 

二、Class文件

1. 文件格式 

2. 常量池项目

3.  属性类型

三、Class文件实例

1. 源代码

2. javap分析Class文件

四、字节码指令

五、参考资料


一、javac编译

1. 编译过程

        javac命令由Java语言编写,目的将Java源码转变成字节码(只完成源码到抽象语法树或字节码的生成),JDK12源码其运行入口是com.sun.tools.javac.Main#main。javac主体代码如下图所示。com.sun.tools.javac.main.JavaCompiler#compile核心方法。

        javac编译过程:一个准备(初始化插入式注解处理器);三个处理(解析与填充符号表、处理注解处理器、语义分析与字节码生成),如下图所示。

        需要注意的是:生成<init>()、<clinit>()方法在编译期完成;Lombok操作通过插入式注解处理器完成对字段的getter()和setter()方法

2. 语法糖 

二、Class文件

1. 文件格式 

        Class文件是字节为单位的二进制流,有两种数据类型:无符号数、表,如下图所示。Class文件不保存方法、字段最终的内存布局信息,JVM运行期才能找到内存入口地址

        Class文件格式如下表所示,主要有:常量池、字段表、方法表、属性表等。Class文件可以使用十六进制编辑器WinHex打开。注意:常量池(constant_pool)的数量是constant_pool_count减1,若为0说明“不引用任何常量池项目”;而其他表从0开始计数。

数据类型

名称

数量

作用及特点

u4

magic

1

1.魔数:确定文件是否是Class文件;

2.固定值:0xCAFEBABE

u2

minnor_version

1

次版本

u2

major_version

1

1.版本号;

2.JDK向前兼容老版本,则不能向后兼容新版本。

u2

constant_pool_count

1

1.常量池容量计数数量;

2.索引从1开始,其他表从0开始

3.若为0,则说明不引用任何常量池项目

cp_info

constant_pool

constant_pool_count

 - 1

1.常量池,有两大类常量:字面量、符号引用

2.17种不同类型常量,如:

   CONSTANT_Utf8_info、  

   CONSTANT_Class_info

   CONSTANT_Fieldref_info   

   CONSTANT_Methodref_info......

u2

access_flags

1

1.类或接口的访问修饰符;

2.如:ACC_PUBLIC(是否为public修饰)。

u2

this_class

1

类索引:当前类的全限定名

u2

super_class

1

1.父类索引:当前类的父类的全限定名;

2.java.lang.Object外,所有类的父类值都不为0

u2

interfaces_count

1

1.接口索引的数量;

2.没有实现任何接口时,该值为0

u2

interfaces

interfaces_count

1.接口索引:当前类的所有接口的全限定名;

2.接口从左往右的顺序在该表中

u2

fields_count

1

类或接口的字段数量

field_info

fields

fields_count

1.类或接口的字段(实例变量,类变量);

2.不包括:方法内局部变量;

3.内容有:修饰符、在常量池中索引、简单名称、描述符、属性表(attribute_info;

4.描述符:字段的数据类型、方法的参数列表及返回值

5.不会列出父类或接口的字段

6.可能含有JVM自动生成的字段,如:this字段

u2

methods_count

1

类或接口的方法数量

method_info

methods

methods_count

1.类或接口的方法(实例方法,类方法);

2.内容有:修饰符、在常量池中索引、简单名称、描述符、属性表(attribute_infoCode;

3.“描述符:字段的数据类型、方法的参数列表及返回值

4.不会列出父类或接口的方法(重写除外)

5.可能含有JVM自动生成的方法,如:<init>()<cinit>()方法

u2

attributes_count

1

属性表数量

attribute_info

attributes

attributes_count

1.Class文件、字段、方法都有自己的属性;

2.属性只要不重名,任何编译器都可以添加自己的属性信息

2. 常量池项目

        常量池有两大类常量:字面量、符号引用。当类加载时,从常量池获得对应的符号引用,再在类创建或运行解析时,翻译到具体的内存地址中。如下表所示是17种不同类型的常量。

        “描述符”作用是描述字段的数据类型、方法的参数列表(包括:数量、类型、顺序)、返回值。数组类型,每一个维度用前置的“[”标识,如:void inc(int[ ] ints)其描述符为([I)V。下表所示是描述符标识字符含义。

3.  属性类型

        Class文件、字段、方法都有自己的属性,这些属性存储到属性表(attribute_info),《Java虚拟机规范》允许属性只要不重名,任何编译器都可以添加自己的属性信息。

        如下表所示是常用属性介绍,其中整个Class文件中,只有Code属性描述方法体的代码,其他所有数据项目都是描述元数据

常用属性

使用位置

含义

Code

方法表

1.作用:描述方法体代码,注意:不是所有方法都有Code属性,如:接口、抽象类的方法等;

2.Code属性表中常用参数:

  max_stack:操作数栈的最大深度;

  max_locals:局部变量表的最大slot数量(不是空间大小);

  args_size:方法的参数数量,注意:若实例方法,则有this参数;

  code:方法体的字节码指令流;

  .....

LineNumberTable

Code属性

1.源码行号与字节码指令行的对应关系;

2.字节码指令的“行”:是相对于方法体开始的偏移量。

LocalVariableTable

Code属性

1.方法的局部变量描述;

2.注意:若实例方法,则有this参数;

3.结构中:start_pc(变量开始的字节码偏移量) + length(长度)决定变量的作用域。

StackMapTable

Code属性

1.目的:类加载时字节码验证阶段进行类型检查(新类型检查器);

2.含义:0或多个栈映射帧(代表字节码偏移量),即:执行到该字节码时局部变量表和操作数栈的验证类型。

ConstantValue

字段表

1.常量值:为static修饰的变量赋值的值;

2.常量值只能是:基本数据类型、String。

Exceptions

方法表

方法抛出的异常列表 

InnerClasses

类文件

内部类列表

Signature

类、方法表、

字段表

1.记录泛型签名信息,如:类型变量、类型参数等;

2.反射API就是根据这个属性来获取泛型信息。

MethodParameters

方法表

记录方法的各个形参和信息

Synthetic

类、方法表、

字段表

1.标识方法或字段是编译器自动生成,至少有Synthetic或ACC_SYNTHETIC一个;

2.如:实例构造器<init>()、类构造器<cinit>();

其他:Deprecated(含有@Deprecated)、EnclosingMethod(含有局部类或匿名类)、

           RuntimeVisibleAnnotations(运行时可见的注解,反射可调用)、SourceFile(记录源文件名称)、

           RuntimeInvisibleAnnotations(运行时不可见的注解,反射不可调用)、

           AnnotationDefault(含有注解类元素默认值)、Modlue(记录模块信息)、

           BootstrapMethods(保存invokedynamic指令引用的引导方法限定符)、

           ......

三、Class文件实例

1. 源代码

        如下代码,用javac编译成Class文件。

package com.common.instance.demo.core.serviceLevel;

import com.alibaba.fastjson.JSON;
import com.log.util.LogUtil;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.*;

/**
 * @description 一级业务线程池处理业务
 * @author tcm
 * @version 1.0.0
 * @date 2021/9/29 16:01
 **/
@Component
public class OneLevelAsyncContext implements InitializingBean {

    private final String URI = "uri";
    private final String PARAMS = "params";

    private AsyncListener asyncListener;
    private LinkedBlockingDeque<Runnable> queue;
    private ThreadPoolExecutor executor;

    public Object submitFuture(final HttpServletRequest request, final Callable<Object> task) throws ExecutionException, InterruptedException {
        // 获取请求URI
        final String uri = request.getRequestURI();
        // 获取请求参数
        final Map<String, String[]> params = request.getParameterMap();

        // 开启异步上下文
        final AsyncContext asyncContext = request.startAsync();
        asyncContext.getRequest().setAttribute(URI, uri);
        asyncContext.getRequest().setAttribute(PARAMS, params);
        // 超时设置
        asyncContext.setTimeout(2 * 1000);
        if (Objects.nonNull(asyncListener)) {
            asyncContext.addListener(this.asyncListener);
        }

        // 线程池处理业务
        Future<Object> future = executor.submit(new Callable<Object>() {
            @Override
            public Object call() throws Exception {
                // 业务处理
                Object result = task.call();
                return result;
            }
        });
        // 完成异步上下文,否则报超时等异常
        asyncContext.complete();
        return future.get();
    }



    // 完成初始化配置
    @Override
    public void afterPropertiesSet() throws Exception {
        // 线程池大小
        int corePoolSize = Integer.parseInt("100");
        // 最大线程池大小
        int maxNumPoolSize = Integer.parseInt("200");
        // 任务队列
        queue = new LinkedBlockingDeque<Runnable>();
        // 创建线程池
        executor = new ThreadPoolExecutor(corePoolSize, maxNumPoolSize, 100, TimeUnit.MILLISECONDS, queue);

        executor.allowCoreThreadTimeOut(true);
        // 线程池饱和处理
        executor.setRejectedExecutionHandler(new RejectedExecutionHandler() {
            @Override
            public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
                if (r instanceof CanceledCallable) {
                    CanceledCallable cc = ((CanceledCallable) r);
                    AsyncContext asyncContext = cc.asyncContext;
                    try {
                        ServletRequest request = asyncContext.getRequest();
                        String uri = (String) request.getAttribute(URI);
                        Map params = (Map) request.getAttribute(PARAMS);

                        LogUtil.error(String.format("async request %s, uri:%s, params:%s", "rejectedExecution", uri, JSON.toJSONString(params)));
                    } catch (Exception ex) {

                    }
                    try {
                        HttpServletResponse response = (HttpServletResponse) asyncContext.getResponse();
                        response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                    } finally {
                        asyncContext.complete();
                    }
                }
            }

        });

        // 创建监听器
        if (Objects.isNull(asyncListener)) {
            asyncListener = new AsyncListener() {
                @Override
                public void onComplete(AsyncEvent asyncEvent) throws IOException {

                }

                @Override
                public void onTimeout(AsyncEvent asyncEvent) throws IOException {
                    AsyncContext asyncContext = asyncEvent.getAsyncContext();
                    try {
                        ServletRequest request = asyncContext.getRequest();
                        String uri = (String) request.getAttribute(URI);
                        Map params = (Map) request.getAttribute(PARAMS);

                        LogUtil.error(String.format("async request timeout, uri:%s, params:%s", uri, JSON.toJSONString(params)));
                    } catch (Exception e) {}
                    try {
                        HttpServletResponse resp = (HttpServletResponse) asyncContext.getResponse();
                        resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                    } finally {
                        asyncContext.complete();
                    }
                }

                @Override
                public void onError(AsyncEvent asyncEvent) throws IOException {
                    AsyncContext asyncContext = asyncEvent.getAsyncContext();
                    try {
                        ServletRequest request = asyncContext.getRequest();
                        String uri = (String) request.getAttribute(URI);
                        Map params = (Map) request.getAttribute(PARAMS);

                        LogUtil.error(String.format("async request error, uri:%s, params:%s", uri, JSON.toJSONString(params)));
                    } catch (Exception e) {}
                    try {
                        HttpServletResponse resp = (HttpServletResponse) asyncContext.getResponse();
                        resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
                    } finally {
                        asyncContext.complete();
                    }
                }

                @Override
                public void onStartAsync(AsyncEvent asyncEvent) throws IOException {

                }

            };
        }
    }

}

2. javap分析Class文件

        javap命令分析Class文件,如:javap -verbose OneLevelAsyncContext.class,代码所示。

Classfile /E:/Idea Project/instance-demo/target/classes/com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext.class
  Last modified 2023-7-22; size 4120 bytes
  MD5 checksum ab1d73e3259040031896505e9ed1e1bb
  Compiled from "OneLevelAsyncContext.java"
public class com.common.instance.demo.core.serviceLevel.OneLevelAsyncContext implements org.springframework.beans.factory.InitializingBean
  minor version: 0
  major version: 52
  flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
    #1 = Methodref          #42.#99       // java/lang/Object."<init>":()V
    #2 = String             #70           // uri
    #3 = Fieldref           #10.#100      // com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext.URI:Ljava/lang/String;
    #4 = String             #71           // params
    #5 = Fieldref           #10.#101      // com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext.PARAMS:Ljava/lang/String;
    #6 = InterfaceMethodref #102.#103     // javax/servlet/http/HttpServletRequest.getRequestURI:()Ljava/lang/String;
    #7 = InterfaceMethodref #102.#104     // javax/servlet/http/HttpServletRequest.getParameterMap:()Ljava/util/Map;
    #8 = InterfaceMethodref #102.#105     // javax/servlet/http/HttpServletRequest.startAsync:()Ljavax/servlet/AsyncContext;
    #9 = InterfaceMethodref #106.#107     // javax/servlet/AsyncContext.getRequest:()Ljavax/servlet/ServletRequest;
   #10 = Class              #108          // com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext
   #11 = InterfaceMethodref #109.#110     // javax/servlet/ServletRequest.setAttribute:(Ljava/lang/String;Ljava/lang/Object;)V
   #12 = Long               2000l
   #14 = InterfaceMethodref #106.#111     // javax/servlet/AsyncContext.setTimeout:(J)V
   #15 = Fieldref           #10.#112      // com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext.asyncListener:Ljavax/servlet/AsyncListener;
   #16 = Methodref          #113.#114     // java/util/Objects.nonNull:(Ljava/lang/Object;)Z
   #17 = InterfaceMethodref #106.#115     // javax/servlet/AsyncContext.addListener:(Ljavax/servlet/AsyncListener;)V
   #18 = Fieldref           #10.#116      // com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext.executor:Ljava/util/concurrent/ThreadPoolExecutor;
   #19 = Class              #117          // com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$1
   #20 = Methodref          #19.#118      // com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$1."<init>":(Lcom/common/instance/demo/core/serviceLevel/OneLevelAsyncContext;Ljava/util/concurrent/Callable;)V
   #21 = Methodref          #30.#119      // java/util/concurrent/ThreadPoolExecutor.submit:(Ljava/util/concurrent/Callable;)Ljava/util/concurrent/Future;
   #22 = InterfaceMethodref #106.#120     // javax/servlet/AsyncContext.complete:()V
   #23 = InterfaceMethodref #121.#122     // java/util/concurrent/Future.get:()Ljava/lang/Object;
   #24 = String             #123          // 100
   #25 = Methodref          #124.#125     // java/lang/Integer.parseInt:(Ljava/lang/String;)I
   #26 = String             #126          // 200
   #27 = Class              #127          // java/util/concurrent/LinkedBlockingDeque
   #28 = Methodref          #27.#99       // java/util/concurrent/LinkedBlockingDeque."<init>":()V
   #29 = Fieldref           #10.#128      // com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext.queue:Ljava/util/concurrent/LinkedBlockingDeque;
   #30 = Class              #129          // java/util/concurrent/ThreadPoolExecutor
   #31 = Long               100l
   #33 = Fieldref           #130.#131     // java/util/concurrent/TimeUnit.MILLISECONDS:Ljava/util/concurrent/TimeUnit;
   #34 = Methodref          #30.#132      // java/util/concurrent/ThreadPoolExecutor."<init>":(IIJLjava/util/concurrent/TimeUnit;Ljava/util/concurrent/BlockingQueue;)V
   #35 = Methodref          #30.#133      // java/util/concurrent/ThreadPoolExecutor.allowCoreThreadTimeOut:(Z)V
   #36 = Class              #134          // com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$2
   #37 = Methodref          #36.#135      // com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$2."<init>":(Lcom/common/instance/demo/core/serviceLevel/OneLevelAsyncContext;)V
   #38 = Methodref          #30.#136      // java/util/concurrent/ThreadPoolExecutor.setRejectedExecutionHandler:(Ljava/util/concurrent/RejectedExecutionHandler;)V
   #39 = Methodref          #113.#137     // java/util/Objects.isNull:(Ljava/lang/Object;)Z
   #40 = Class              #138          // com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$3
   #41 = Methodref          #40.#135      // com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$3."<init>":(Lcom/common/instance/demo/core/serviceLevel/OneLevelAsyncContext;)V
   #42 = Class              #139          // java/lang/Object
   #43 = Class              #140          // org/springframework/beans/factory/InitializingBean
   #44 = Utf8               InnerClasses
   #45 = Utf8               URI
   #46 = Utf8               Ljava/lang/String;
   #47 = Utf8               ConstantValue
   #48 = Utf8               PARAMS
   #49 = Utf8               asyncListener
   #50 = Utf8               Ljavax/servlet/AsyncListener;
   #51 = Utf8               queue
   #52 = Utf8               Ljava/util/concurrent/LinkedBlockingDeque;
   #53 = Utf8               Signature
   #54 = Utf8               Ljava/util/concurrent/LinkedBlockingDeque<Ljava/lang/Runnable;>;
   #55 = Utf8               executor
   #56 = Utf8               Ljava/util/concurrent/ThreadPoolExecutor;
   #57 = Utf8               <init>
   #58 = Utf8               ()V
   #59 = Utf8               Code
   #60 = Utf8               LineNumberTable
   #61 = Utf8               LocalVariableTable
   #62 = Utf8               this
   #63 = Utf8               Lcom/common/instance/demo/core/serviceLevel/OneLevelAsyncContext;
   #64 = Utf8               submitFuture
   #65 = Utf8               (Ljavax/servlet/http/HttpServletRequest;Ljava/util/concurrent/Callable;)Ljava/lang/Object;
   #66 = Utf8               request
   #67 = Utf8               Ljavax/servlet/http/HttpServletRequest;
   #68 = Utf8               task
   #69 = Utf8               Ljava/util/concurrent/Callable;
   #70 = Utf8               uri
   #71 = Utf8               params
   #72 = Utf8               Ljava/util/Map;
   #73 = Utf8               asyncContext
   #74 = Utf8               Ljavax/servlet/AsyncContext;
   #75 = Utf8               future
   #76 = Utf8               Ljava/util/concurrent/Future;
   #77 = Utf8               LocalVariableTypeTable
   #78 = Utf8               Ljava/util/concurrent/Callable<Ljava/lang/Object;>;
   #79 = Utf8               Ljava/util/Map<Ljava/lang/String;[Ljava/lang/String;>;
   #80 = Utf8               Ljava/util/concurrent/Future<Ljava/lang/Object;>;
   #81 = Utf8               StackMapTable
   #82 = Class              #141          // java/lang/String
   #83 = Class              #142          // java/util/Map
   #84 = Class              #143          // javax/servlet/AsyncContext
   #85 = Utf8               Exceptions
   #86 = Class              #144          // java/util/concurrent/ExecutionException
   #87 = Class              #145          // java/lang/InterruptedException
   #88 = Utf8               MethodParameters
   #89 = Utf8               (Ljavax/servlet/http/HttpServletRequest;Ljava/util/concurrent/Callable<Ljava/lang/Object;>;)Ljava/lang/Object;
   #90 = Utf8               afterPropertiesSet
   #91 = Utf8               corePoolSize
   #92 = Utf8               I
   #93 = Utf8               maxNumPoolSize
   #94 = Class              #146          // java/lang/Exception
   #95 = Utf8               SourceFile
   #96 = Utf8               OneLevelAsyncContext.java
   #97 = Utf8               RuntimeVisibleAnnotations
   #98 = Utf8               Lorg/springframework/stereotype/Component;
   #99 = NameAndType        #57:#58       // "<init>":()V
  #100 = NameAndType        #45:#46       // URI:Ljava/lang/String;
  #101 = NameAndType        #48:#46       // PARAMS:Ljava/lang/String;
  #102 = Class              #147          // javax/servlet/http/HttpServletRequest
  #103 = NameAndType        #148:#149     // getRequestURI:()Ljava/lang/String;
  #104 = NameAndType        #150:#151     // getParameterMap:()Ljava/util/Map;
  #105 = NameAndType        #152:#153     // startAsync:()Ljavax/servlet/AsyncContext;
  #106 = Class              #143          // javax/servlet/AsyncContext
  #107 = NameAndType        #154:#155     // getRequest:()Ljavax/servlet/ServletRequest;
  #108 = Utf8               com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext
  #109 = Class              #156          // javax/servlet/ServletRequest
  #110 = NameAndType        #157:#158     // setAttribute:(Ljava/lang/String;Ljava/lang/Object;)V
  #111 = NameAndType        #159:#160     // setTimeout:(J)V
  #112 = NameAndType        #49:#50       // asyncListener:Ljavax/servlet/AsyncListener;
  #113 = Class              #161          // java/util/Objects
  #114 = NameAndType        #162:#163     // nonNull:(Ljava/lang/Object;)Z
  #115 = NameAndType        #164:#165     // addListener:(Ljavax/servlet/AsyncListener;)V
  #116 = NameAndType        #55:#56       // executor:Ljava/util/concurrent/ThreadPoolExecutor;
  #117 = Utf8               com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$1
  #118 = NameAndType        #57:#166      // "<init>":(Lcom/common/instance/demo/core/serviceLevel/OneLevelAsyncContext;Ljava/util/concurrent/Callable;)V
  #119 = NameAndType        #167:#168     // submit:(Ljava/util/concurrent/Callable;)Ljava/util/concurrent/Future;
  #120 = NameAndType        #169:#58      // complete:()V
  #121 = Class              #170          // java/util/concurrent/Future
  #122 = NameAndType        #171:#172     // get:()Ljava/lang/Object;
  #123 = Utf8               100
  #124 = Class              #173          // java/lang/Integer
  #125 = NameAndType        #174:#175     // parseInt:(Ljava/lang/String;)I
  #126 = Utf8               200
  #127 = Utf8               java/util/concurrent/LinkedBlockingDeque
  #128 = NameAndType        #51:#52       // queue:Ljava/util/concurrent/LinkedBlockingDeque;
  #129 = Utf8               java/util/concurrent/ThreadPoolExecutor
  #130 = Class              #176          // java/util/concurrent/TimeUnit
  #131 = NameAndType        #177:#178     // MILLISECONDS:Ljava/util/concurrent/TimeUnit;
  #132 = NameAndType        #57:#179      // "<init>":(IIJLjava/util/concurrent/TimeUnit;Ljava/util/concurrent/BlockingQueue;)V
  #133 = NameAndType        #180:#181     // allowCoreThreadTimeOut:(Z)V
  #134 = Utf8               com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$2
  #135 = NameAndType        #57:#182      // "<init>":(Lcom/common/instance/demo/core/serviceLevel/OneLevelAsyncContext;)V
  #136 = NameAndType        #183:#184     // setRejectedExecutionHandler:(Ljava/util/concurrent/RejectedExecutionHandler;)V
  #137 = NameAndType        #185:#163     // isNull:(Ljava/lang/Object;)Z
  #138 = Utf8               com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$3
  #139 = Utf8               java/lang/Object
  #140 = Utf8               org/springframework/beans/factory/InitializingBean
  #141 = Utf8               java/lang/String
  #142 = Utf8               java/util/Map
  #143 = Utf8               javax/servlet/AsyncContext
  #144 = Utf8               java/util/concurrent/ExecutionException
  #145 = Utf8               java/lang/InterruptedException
  #146 = Utf8               java/lang/Exception
  #147 = Utf8               javax/servlet/http/HttpServletRequest
  #148 = Utf8               getRequestURI
  #149 = Utf8               ()Ljava/lang/String;
  #150 = Utf8               getParameterMap
  #151 = Utf8               ()Ljava/util/Map;
  #152 = Utf8               startAsync
  #153 = Utf8               ()Ljavax/servlet/AsyncContext;
  #154 = Utf8               getRequest
  #155 = Utf8               ()Ljavax/servlet/ServletRequest;
  #156 = Utf8               javax/servlet/ServletRequest
  #157 = Utf8               setAttribute
  #158 = Utf8               (Ljava/lang/String;Ljava/lang/Object;)V
  #159 = Utf8               setTimeout
  #160 = Utf8               (J)V
  #161 = Utf8               java/util/Objects
  #162 = Utf8               nonNull
  #163 = Utf8               (Ljava/lang/Object;)Z
  #164 = Utf8               addListener
  #165 = Utf8               (Ljavax/servlet/AsyncListener;)V
  #166 = Utf8               (Lcom/common/instance/demo/core/serviceLevel/OneLevelAsyncContext;Ljava/util/concurrent/Callable;)V
  #167 = Utf8               submit
  #168 = Utf8               (Ljava/util/concurrent/Callable;)Ljava/util/concurrent/Future;
  #169 = Utf8               complete
  #170 = Utf8               java/util/concurrent/Future
  #171 = Utf8               get
  #172 = Utf8               ()Ljava/lang/Object;
  #173 = Utf8               java/lang/Integer
  #174 = Utf8               parseInt
  #175 = Utf8               (Ljava/lang/String;)I
  #176 = Utf8               java/util/concurrent/TimeUnit
  #177 = Utf8               MILLISECONDS
  #178 = Utf8               Ljava/util/concurrent/TimeUnit;
  #179 = Utf8               (IIJLjava/util/concurrent/TimeUnit;Ljava/util/concurrent/BlockingQueue;)V
  #180 = Utf8               allowCoreThreadTimeOut
  #181 = Utf8               (Z)V
  #182 = Utf8               (Lcom/common/instance/demo/core/serviceLevel/OneLevelAsyncContext;)V
  #183 = Utf8               setRejectedExecutionHandler
  #184 = Utf8               (Ljava/util/concurrent/RejectedExecutionHandler;)V
  #185 = Utf8               isNull
{
  public com.common.instance.demo.core.serviceLevel.OneLevelAsyncContext();
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=2, locals=1, args_size=1
         0: aload_0
         1: invokespecial #1                  // Method java/lang/Object."<init>":()V
         4: aload_0
         5: ldc           #2                  // String uri
         7: putfield      #3                  // Field URI:Ljava/lang/String;
        10: aload_0
        11: ldc           #4                  // String params
        13: putfield      #5                  // Field PARAMS:Ljava/lang/String;
        16: return
      LineNumberTable:
        line 23: 0
        line 25: 4
        line 26: 10
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      17     0  this   Lcom/common/instance/demo/core/serviceLevel/OneLevelAsyncContext;

  public java.lang.Object submitFuture(javax.servlet.http.HttpServletRequest, java.util.concurrent.Callable<java.lang.Object>) throws java.util.concurrent.ExecutionException, java.lang.InterruptedException;
    descriptor: (Ljavax/servlet/http/HttpServletRequest;Ljava/util/concurrent/Callable;)Ljava/lang/Object;
    flags: ACC_PUBLIC
    Code:
      stack=5, locals=7, args_size=3
         0: aload_1
         1: invokeinterface #6,  1            // InterfaceMethod javax/servlet/http/HttpServletRequest.getRequestURI:()Ljava/lang/String;
         6: astore_3
         7: aload_1
         8: invokeinterface #7,  1            // InterfaceMethod javax/servlet/http/HttpServletRequest.getParameterMap:()Ljava/util/Map;
        13: astore        4
        15: aload_1
        16: invokeinterface #8,  1            // InterfaceMethod javax/servlet/http/HttpServletRequest.startAsync:()Ljavax/servlet/AsyncContext;
        21: astore        5
        23: aload         5
        25: invokeinterface #9,  1            // InterfaceMethod javax/servlet/AsyncContext.getRequest:()Ljavax/servlet/ServletRequest;
        30: ldc           #2                  // String uri
        32: aload_3
        33: invokeinterface #11,  3           // InterfaceMethod javax/servlet/ServletRequest.setAttribute:(Ljava/lang/String;Ljava/lang/Object;)V
        38: aload         5
        40: invokeinterface #9,  1            // InterfaceMethod javax/servlet/AsyncContext.getRequest:()Ljavax/servlet/ServletRequest;
        45: ldc           #4                  // String params
        47: aload         4
        49: invokeinterface #11,  3           // InterfaceMethod javax/servlet/ServletRequest.setAttribute:(Ljava/lang/String;Ljava/lang/Object;)V
        54: aload         5
        56: ldc2_w        #12                 // long 2000l
        59: invokeinterface #14,  3           // InterfaceMethod javax/servlet/AsyncContext.setTimeout:(J)V
        64: aload_0
        65: getfield      #15                 // Field asyncListener:Ljavax/servlet/AsyncListener;
        68: invokestatic  #16                 // Method java/util/Objects.nonNull:(Ljava/lang/Object;)Z
        71: ifeq          85
        74: aload         5
        76: aload_0
        77: getfield      #15                 // Field asyncListener:Ljavax/servlet/AsyncListener;
        80: invokeinterface #17,  2           // InterfaceMethod javax/servlet/AsyncContext.addListener:(Ljavax/servlet/AsyncListener;)V
        85: aload_0
        86: getfield      #18                 // Field executor:Ljava/util/concurrent/ThreadPoolExecutor;
        89: new           #19                 // class com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$1
        92: dup
        93: aload_0
        94: aload_2
        95: invokespecial #20                 // Method com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$1."<init>":(Lcom/common/instance/demo/core/serviceLevel/OneLevelAsyncContext;Ljava/util/concurrent/Callable;)V
        98: invokevirtual #21                 // Method java/util/concurrent/ThreadPoolExecutor.submit:(Ljava/util/concurrent/Callable;)Ljava/util/concurrent/Future;
       101: astore        6
       103: aload         5
       105: invokeinterface #22,  1           // InterfaceMethod javax/servlet/AsyncContext.complete:()V
       110: aload         6
       112: invokeinterface #23,  1           // InterfaceMethod java/util/concurrent/Future.get:()Ljava/lang/Object;
       117: areturn
      LineNumberTable:
        line 34: 0
        line 36: 7
        line 39: 15
        line 40: 23
        line 41: 38
        line 43: 54
        line 44: 64
        line 45: 74
        line 49: 85
        line 58: 103
        line 59: 110
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0     118     0  this   Lcom/common/instance/demo/core/serviceLevel/OneLevelAsyncContext;
            0     118     1 request   Ljavax/servlet/http/HttpServletRequest;
            0     118     2  task   Ljava/util/concurrent/Callable;
            7     111     3   uri   Ljava/lang/String;
           15     103     4 params   Ljava/util/Map;
           23      95     5 asyncContext   Ljavax/servlet/AsyncContext;
          103      15     6 future   Ljava/util/concurrent/Future;
      LocalVariableTypeTable:
        Start  Length  Slot  Name   Signature
            0     118     2  task   Ljava/util/concurrent/Callable<Ljava/lang/Object;>;
           15     103     4 params   Ljava/util/Map<Ljava/lang/String;[Ljava/lang/String;>;
          103      15     6 future   Ljava/util/concurrent/Future<Ljava/lang/Object;>;
      StackMapTable: number_of_entries = 1
        frame_type = 254 /* append */
          offset_delta = 85
          locals = [ class java/lang/String, class java/util/Map, class javax/servlet/AsyncContext ]
    Exceptions:
      throws java.util.concurrent.ExecutionException, java.lang.InterruptedException
    MethodParameters:
      Name                           Flags
      request                        final
      task                           final
    Signature: #89                          // (Ljavax/servlet/http/HttpServletRequest;Ljava/util/concurrent/Callable<Ljava/lang/Object;>;)Ljava/lang/Object;

  public void afterPropertiesSet() throws java.lang.Exception;
    descriptor: ()V
    flags: ACC_PUBLIC
    Code:
      stack=9, locals=3, args_size=1
         0: ldc           #24                 // String 100
         2: invokestatic  #25                 // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
         5: istore_1
         6: ldc           #26                 // String 200
         8: invokestatic  #25                 // Method java/lang/Integer.parseInt:(Ljava/lang/String;)I
        11: istore_2
        12: aload_0
        13: new           #27                 // class java/util/concurrent/LinkedBlockingDeque
        16: dup
        17: invokespecial #28                 // Method java/util/concurrent/LinkedBlockingDeque."<init>":()V
        20: putfield      #29                 // Field queue:Ljava/util/concurrent/LinkedBlockingDeque;
        23: aload_0
        24: new           #30                 // class java/util/concurrent/ThreadPoolExecutor
        27: dup
        28: iload_1
        29: iload_2
        30: ldc2_w        #31                 // long 100l
        33: getstatic     #33                 // Field java/util/concurrent/TimeUnit.MILLISECONDS:Ljava/util/concurrent/TimeUnit;
        36: aload_0
        37: getfield      #29                 // Field queue:Ljava/util/concurrent/LinkedBlockingDeque;
        40: invokespecial #34                 // Method java/util/concurrent/ThreadPoolExecutor."<init>":(IIJLjava/util/concurrent/TimeUnit;Ljava/util/concurrent/BlockingQueue;)V
        43: putfield      #18                 // Field executor:Ljava/util/concurrent/ThreadPoolExecutor;
        46: aload_0
        47: getfield      #18                 // Field executor:Ljava/util/concurrent/ThreadPoolExecutor;
        50: iconst_1
        51: invokevirtual #35                 // Method java/util/concurrent/ThreadPoolExecutor.allowCoreThreadTimeOut:(Z)V
        54: aload_0
        55: getfield      #18                 // Field executor:Ljava/util/concurrent/ThreadPoolExecutor;
        58: new           #36                 // class com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$2
        61: dup
        62: aload_0
        63: invokespecial #37                 // Method com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$2."<init>":(Lcom/common/instance/demo/core/serviceLevel/OneLevelAsyncContext;)V
        66: invokevirtual #38                 // Method java/util/concurrent/ThreadPoolExecutor.setRejectedExecutionHandler:(Ljava/util/concurrent/RejectedExecutionHandler;)V
        69: aload_0
        70: getfield      #15                 // Field asyncListener:Ljavax/servlet/AsyncListener;
        73: invokestatic  #39                 // Method java/util/Objects.isNull:(Ljava/lang/Object;)Z
        76: ifeq          91
        79: aload_0
        80: new           #40                 // class com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$3
        83: dup
        84: aload_0
        85: invokespecial #41                 // Method com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$3."<init>":(Lcom/common/instance/demo/core/serviceLevel/OneLevelAsyncContext;)V
        88: putfield      #15                 // Field asyncListener:Ljavax/servlet/AsyncListener;
        91: return
      LineNumberTable:
        line 68: 0
        line 70: 6
        line 72: 12
        line 74: 23
        line 76: 46
        line 78: 54
        line 105: 69
        line 106: 79
        line 155: 91
      LocalVariableTable:
        Start  Length  Slot  Name   Signature
            0      92     0  this   Lcom/common/instance/demo/core/serviceLevel/OneLevelAsyncContext;
            6      86     1 corePoolSize   I
           12      80     2 maxNumPoolSize   I
      StackMapTable: number_of_entries = 1
        frame_type = 253 /* append */
          offset_delta = 91
          locals = [ int, int ]
    Exceptions:
      throws java.lang.Exception
}
SourceFile: "OneLevelAsyncContext.java"
RuntimeVisibleAnnotations:
  0: #98()
InnerClasses:
     #40; //class com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$3
     #36; //class com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$2
     #19; //class com/common/instance/demo/core/serviceLevel/OneLevelAsyncContext$1

四、字节码指令

        Java各种语法、关键字、常量变量、符号运算的语义最终都会由多个字节码指令组合来表达。Java虚拟机字节码指令组成如下所示:操作码(Opcode)、操作数(Operand)。

       Java虚拟机面向操作数栈而不是面向寄存器的架构,其总数不超过256条(单字节),指令分类如下表所示。 

指令类型

指令作用

指令

加载和存储

局部表加载到操作数栈

1.iload、iload_<n>、aload、aload_<n>、......;

2._<n>:其中n表示局部变量表的slot索引位置

操作数栈存储到局部表

1.istore、istore_<n>、astore、astore_<n>、......;

2._<n>:其中n表示局部变量表的slot索引位置。

常量加载到操作数栈

1.iconst_<i>、aconst_null、bipush、sipush、ldc、......;

2.iconst_<i>表示:int型的常量<i>加载到操作数栈。

扩充局部变量表的访问索引

wide

运算指令

加法指令

iadd、ladd、fadd、dadd

减法指令

isub、lsub、fsub、dsub

局部变量自增指令

iinc

比较指令

dcmpg、dcmpl、fcmpg、fcmpl、cmp

......

imul、idev、irem、ineg、ishl、ior、iadd、ixor、......

对象创建和访问

类实例创建

new

数组创建

newarray、anewarray、multianewarray

访问实例字段或类字段

getfield、putfield、getstatic、putstatic

数组元素加载到操作数栈

iaload、aaload、......

操作数栈存储到数组元素

iastore、aastore、......

获取数组长度

arraylength

检查类实例类型

instanceof、checkcast

操作数栈管理

栈顶一个或两个元素出栈

pop、pop2

栈顶一个或两个元素复制或双份复制重新压入栈顶

dup、dup2、dup_x1、dup2_x1、dup_x2、dup2_x2

最顶端两个元素互换

swap

控制转移

条件分支

ifeq、iflt、ifnull、ificmplt、ifacmpeq、......

复合条件分支

tableswitch、lookupswitch

无条件分支

goto、goto_w、......

方法调用和返回

调用对象实例方法

invokevirtual(运行时实际类型进行动态分派 _ 重写

调用接口方法

invokeinterface(运行时实现该接口的对象,找到合适则调用)

调用实例初始化、私有、父类方法

invokespecial(实例初始化、私有、父类方法)

调用类静态方法

invokestatic(static方法)

动态调用用户设定的方法

invokedunamic(运行时动态解析调用点限定符所引用的方法)

方法返回

1.return(void、实例初始化、类或接口初始化方法);

2.ireturn、lreturn、freturn、dreturn、areturn

 (byte、short、char、boolean、int型返回使用ireturn)

异常处理

显示抛出异常

athrow(throw语句 + 检测到异常状况自动抛出)

同步处理

synchronized加锁

(都是使用管程Monitor

1.方法的隐式加锁,即:方法访问标志ACC_SYNCHRONIZED;

2.语句块的显示加锁,即:monitorenter + monitorexit

类型转换

宽化类型转换(安全转换)

JVM直接支持:i转l/f/d、l转f/d、f转d

窄化类型转换(强制转换)

i2b、i2c、i2s、l2i、f2l、d2f、......

注意:

   a.i代表int、l代表long、s代表short、b代表byte、c代表char、f代表float、d代表double、a代表reference型;

   b.JVM不直接支持byte、short、char、boolean类型的算术运算,转换为int型运算

   c.算术指令对操作数栈顶的两个元素运算,运算后先移除这两个元素,后计算结果存入栈顶

   d.invokevirtual、invokeinterface、invokespecial、invokestatic调用都固化在JVM内部;而invokedunamic是由用户所设定的引导方法决定的

   e.方法无论正常结果还是异常结束,则每条monitorenter都必须对应monitorexit;

   f.算术运算时,使用NaN(Not a Number)运算,其结果都是NaN。

五、参考资料

jdk/jdk12: log

Java 进阶之字节码剖析_aload_0_C陈三岁的博客-优快云博客

Class文件解析_class 详解_Aur_ora的博客-优快云博客

基于数据挖掘的音乐推荐系统设计与实现 需要一个代码说明,不需要论文 采用python语言,django框架,mysql数据库开发 编程环境:pycharm,mysql8.0 系统分为前台+后台模式开发 网站前台: 用户注册, 登录 搜索音乐,音乐欣赏(可以在线进行播放) 用户登陆时选择相关感兴趣的音乐风格 音乐收藏 音乐推荐算法:(重点) 本课题需要大量用户行为(如播放记录、收藏列表)、音乐特征(如音频特征、歌曲元数据)等数据 (1)根据用户之间相似性或关联性,给一个用户推荐与其相似或有关联的其他用户所感兴趣的音乐; (2)根据音乐之间的相似性或关联性,给一个用户推荐与其感兴趣的音乐相似或有关联的其他音乐。 基于用户的推荐和基于物品的推荐 其中基于用户的推荐是基于用户的相似度找出相似相似用户,然后向目标用户推荐其相似用户喜欢的东西(和你类似的人也喜欢**东西); 而基于物品的推荐是基于物品的相似度找出相似的物品做推荐(喜欢该音乐的人还喜欢了**音乐); 管理员 管理员信息管理 注册用户管理,审核 音乐爬虫(爬虫方式爬取网站音乐数据) 音乐信息管理(上传歌曲MP3,以便前台播放) 音乐收藏管理 用户 用户资料修改 我的音乐收藏 完整前后端源码,部署后可正常运行! 环境说明 开发语言:python后端 python版本:3.7 数据库:mysql 5.7+ 数据库工具:Navicat11+ 开发软件:pycharm
MPU6050是一款广泛应用在无人机、机器人和运动设备中的六轴姿态传感器,它集成了三轴陀螺仪和三轴加速度计。这款传感器能够实时监测并提供设备的角速度和线性加速度数据,对于理解物体的动态运动状态至关重要。在Arduino平台上,通过特定的库文件可以方便地与MPU6050进行通信,获取并解析传感器数据。 `MPU6050.cpp`和`MPU6050.h`是Arduino库的关键组成部分。`MPU6050.h`是头文件,包含了定义传感器接口和函数声明。它定义了类`MPU6050`,该类包含了初始化传感器、读取数据等方法。例如,`begin()`函数用于设置传感器的工作模式和I2C地址,`getAcceleration()`和`getGyroscope()`则分别用于获取加速度和角速度数据。 在Arduino项目中,首先需要包含`MPU6050.h`头文件,然后创建`MPU6050`对象,并调用`begin()`函数初始化传感器。之后,可以通过循环调用`getAcceleration()`和`getGyroscope()`来不断更新传感器读数。为了处理这些原始数据,通常还需要进行校准和滤波,以消除噪声和漂移。 I2C通信协议是MPU6050与Arduino交互的基础,它是一种低引脚数的串行通信协议,允许多个设备共享一对数据线。Arduino板上的Wire库提供了I2C通信的底层支持,使得用户无需深入了解通信细节,就能方便地与MPU6050交互。 MPU6050传感器的数据包括加速度(X、Y、Z轴)和角速度(同样为X、Y、Z轴)。加速度数据可以用来计算物体的静态位置和动态运动,而角速度数据则能反映物体转动的速度。结合这两个数据,可以进一步计算出物体的姿态(如角度和角速度变化)。 在嵌入式开发领域,特别是使用STM32微控制器时,也可以找到类似的库来驱动MPU6050。STM32通常具有更强大的处理能力和更多的GPIO口,可以实现更复杂的控制算法。然而,基本的传感器操作流程和数据处理原理与Arduino平台相似。 在实际应用中,除了基本的传感器读取,还可能涉及到温度补偿、低功耗模式设置、DMP(数字运动处理器)功能的利用等高级特性。DMP可以帮助处理传感器数据,实现更高级的运动估计,减轻主控制器的计算负担。 MPU6050是一个强大的六轴传感器,广泛应用于各种需要实时运动追踪的项目中。通过 Arduino 或 STM32 的库文件,开发者可以轻松地与传感器交互,获取并处理数据,实现各种创新应用。博客和其他开源资源是学习和解决问题的重要途径,通过这些资源,开发者可以获得关于MPU6050的详细信息和实践指南
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值