class类文件结构
定义:任何一个class文件都对应着惟一一个类或接口的定义信息,反过来说,类和接口并不一定都定义在文件里。class文件是一组以8位字节为基础单位的二进制流,各项数据项目严格按照顺序紧凑排列在class文件中。中间没有任何分隔符,这使得整个class文件中存储的内容几乎是程序运行的必要数据,没有间隙。当遇到需要占用8位字节以上空间的数据项时,则会按照高位在前的方式分割成若干个8位字节进行存储。
class文件格式采用伪结构,该种结构中只有两种数据类型:无符号数和表。
无符号数:u1,u2,u4,u8分别代表1个字节,2个字节,4个字节,8个字节的无符号数。无符号数用来描述数字、索引引用、数量值或者按照UTF-8编码构成字符串值。
表:由多个无符号数或者其他表作为数据项构成的复合数据类型,所有表都习惯性以”_info”结尾,整个class文件本质上就是一张表。
接下来,我们会直接从一个class字节码文件分析,这个事例代码是最近写的一个利用redis抢占资源结合发布订阅防并发的案例。我在讲述每个点的时候,大家可以从下面这个字节码中找到对应的位置,对比起来学习。
1、每个class文件的头四个字节称为魔数,它的唯一作用是确定这个文件是否为一个被虚拟机接受的class文件。
2、紧接着魔数的4个字节存储的是class文件的版本号,第5、6是次版本号,第7、8是主版本号。笔者这里是50。版本号向下兼容,低版本的jdk是不接受高版本的class文件的。
3、紧接着主次版本号之后的是常量池入口,常量池可以理解为class文件之中的资源仓库,它是class文件结构中与其他项目关联最多的数据类型,也是占用Class文件空间最大的数据项目之一,同时还是Class文件中第一个出现的表类型数据项目。由于常量的数量是不固定的,所以常量池入口需要防止一个u2类型的数据,代表常量池容量的计数值。注意这个容量的技术是从1开始的。事例中0x00D3=211,210个常量,索引值范围是1~210,设计者把索引为0空出来原因考虑到,满足后面某些指向常量池的索引值的数据在特定情况下需要表达”不引用任何一个常量池项目”的含义,这种情况就可以把索引值置为0来表示。
常量池主要存放了两大类常量:字面量和符号引用。
字面量:比较接近于java语言层面的常量概念,比如文本字符串、final的常量值。
符号引用:类和接口的全限定名、字段的名称和描述符、方法的名称和描述符
由于虚拟机加载Class文件的时候进行动态链接,也就是说,在Class文件中不会保存各个方法、字段的最终内存布局信息,因为这些字段、方法的符号引用不经过运行期转换的话无法得到真正的内存入口地址,也就无法直接被虚拟机使用。JVM运行时,从常量池中获取对应的符号引用,再在类加载中翻译到具体的内存地址之中。(类加载机制我们回头再说,目的是搞清楚我们的文件如何运行起来的。)
常量池中每一项都是一个表,1.7时,14种表,每一个表开始的第一位是一个u1类型的标志位,代表着这个常量属于哪种常量类型。
我们看一下事例中,常量池中的第一个常量:
0x0A=10表示类中方法的符号引用。请看截图
既然到了这里,我们先看CONSTANT_Fieldref_info这个表:
结构是:
我们可以看到方法索引index=0x002F(47),同理第二个索引是0x006C(108)
我们直接从class文件中定位,常量池中的这2个索引的位置:
第一个索引:#47 = Class #160 // java/lang/Object
第二个索引:#108 = NameAndType #64:#65 // “”:()V
对比之前我们确认的第一项常量是:
#1 = Methodref #47.#108 // java/lang/Object.””:()V
注意:字节码文件其实是把索引值都表示出来了,这样我们阅读起来很方便。看下面截图
我们接着往下看: 这表示一个CONSTANT_Class_info
我们再看一下CONSTANT_Class_info的结构:
我们找一下它的类索引–0x006D(109)–找到常量池中的第109个:
上图中展示的就是CONTANT_Utf8_info,我们再来看一下CONTANT_Utf8_info结构:
4、在常量池结束后,紧接着的两个字节代表访问标志,这个标志用于识别一些类或者接口层次的访问信息,包括:还这个Class是类还是接口;是被定义为public类型;是否定义为abstract;如果是类的话,是否被声明为final等。具体标志位见下图:
5、类索引、父类索引、接口索引集合:
类索引和父类索引都是一个u2类型的数据,而接口索引集合是一组u2类型的数据的集合。
类索引用于确定这个类的全限定名。
父类索引用于确定这个父类的全限定名。
接口索引则用来描述这个类实现了哪些接口。
这三个索引都按顺序排列在访问标志之后。这里的索引指向常量池里的常量类,然后再去定位到常量类里的index对应的CONSTANT_Utf8_info
6、字段表集合
7、方法表集合
8、属性表集合
9、字节码指令
10、类加载机制
本次先分享到这里,参考《深入jvm虚拟机》,同时拿了几个其他博友的图片,感谢~
D:\jdk8_64\bin\javap.exe -verbose PublishAndSubscribe.class
Classfile /F:/ormosia/sfeicuss_V20180205/sfeicuss-common/target/classes/com/suning/epps/sfeicuss/common/anticoncurrency/PublishAndSubscribe.class
Last modified 2018-2-9; size 4220 bytes
MD5 checksum 15a03f715334231b3b1b664172c81cdc
Compiled from "PublishAndSubscribe.java"
public class com.suning.epps.sfeicuss.common.anticoncurrency.PublishAndSubscribe
minor version: 0
major version: 50
flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
#1 = Methodref #47.#108 // java/lang/Object."<init>":()V
#2 = Class #109 // com/suning/epps/sfeicuss/common/anticoncurrency/PublishAndSubscribe$1
#3 = Methodref #2.#110 // com/suning/epps/sfeicuss/common/anticoncurrency/PublishAndSubscribe$1."<init>":(Lcom/suning/epps/sfeicuss/common/anticoncurrency/PublishAndSubscribe;)V
#4 = Fieldref #7.#111 // com/suning/epps/sfeicuss/common/anticoncurrency/PublishAndSubscribe.threadLocal:Ljava/lang/ThreadLocal;
#5 = Class #112 // java/lang/StringBuilder
#6 = Methodref #5.#108 // java/lang/StringBuilder."<init>":()V
#7 = Class #113 // com/suning/epps/sfeicuss/common/anticoncurrency/PublishAndSubscribe
#8 = String #114 // PUBANDSUB_KEY_
#9 = Methodref #5.#115 // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
#10 = Methodref #5.#116 // java/lang/StringBuilder.toString:()Ljava/lang/String;
#11 = String #54 // PUB_KEY
#12 = Methodref #117.#118 // com/suning/epps/sfeicuss/common/util/RedisClientUtils.incr:(Ljava/lang/String;)Ljava/lang/Long;
#13 = Methodref #119.#120 // java/lang/Long.longValue:()J
#14 = Fieldref #7.#121 // com/suning/epps/sfeicuss/common/anticoncurrency/PublishAndSubscribe.LOGGER:Lorg/slf4j/Logger;
#15 = String #122 // 抢占到资源
#16 = InterfaceMethodref #123.#124 // org/slf4j/Logger.debug:(Ljava/lang/String;)V
#17 = String #125 // false
#18 = InterfaceMethodref #126.#127 // com/suning/epps/sfeicuss/common/anticoncurrency/CallBack.process:()Ljava/lang/Object;
#19 = InterfaceMethodref #126.#128 // com/suning/epps/sfeicuss/common/anticoncurrency/CallBack.handlerIsSuccessOrNot:(Ljava/lang/Object;)Z
#20 = String #129 // 业务结果:{}
#21 = Methodref #130.#131 // java/lang/Boolean.valueOf:(Z)Ljava/lang/Boolean;
#22 = InterfaceMethodref #123.#132 // org/slf4j/Logger.debug:(Ljava/lang/String;Ljava/lang/Object;)V
#23 = Class #133 // java/lang/Exception
#24 = String #134 // 回调业务处理异常
#25 = InterfaceMethodref #123.#135 // org/slf4j/Logger.error:(Ljava/lang/String;Ljava/lang/Throwable;)V
#26 = Class #136 // com/suning/epps/sfeicuss/common/exception/AppException
#27 = Fieldref #137.#138 // com/suning/epps/sfeicuss/common/enums/ResponseCode.ERROR:Lcom/suning/epps/sfeicuss/common/enums/ResponseCode;
#28 = Methodref #137.#139 // com/suning/epps/sfeicuss/common/enums/ResponseCode.getCode:()Ljava/lang/String;
#29 = Methodref #26.#140 // com/suning/epps/sfeicuss/common/exception/AppException."<init>":(Ljava/lang/String;Ljava/lang/String;)V
#30 = Methodref #117.#141 // com/suning/epps/sfeicuss/common/util/RedisClientUtils.putBeanObj:(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/String;
#31 = String #142 // true
#32 = Methodref #117.#143 // com/suning/epps/sfeicuss/common/util/RedisClientUtils.del:(Ljava/lang/String;)Ljava/lang/Long;
#33 = Methodref #117.#144 // com/suning/epps/sfeicuss/common/util/RedisClientUtils.publish:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Long;
#34 = Methodref #117.#145 // com/suning/epps/sfeicuss/common/util/RedisClientUtils.subscribe:(Ljava/lang/String;)Ljava/lang/String;
#35 = String #77 // subMsg
#36 = Methodref #146.#147 // java/lang/String.equals:(Ljava/lang/Object;)Z
#37 = Methodref #117.#148 // com/suning/epps/sfeicuss/common/util/RedisClientUtils.getBeanObj:(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;
#38 = String #149 // 收到订阅消息:{}
#39 = InterfaceMethodref #126.#150 // com/suning/epps/sfeicuss/common/anticoncurrency/CallBack.handlerResult:(Ljava/lang/Object;)Ljava/lang/Object;
#40 = Methodref #151.#152 // java/lang/ThreadLocal.get:()Ljava/lang/Object;
#41 = Class #153 // java/lang/Integer
#42 = Methodref #41.#154 // java/lang/Integer.intValue:()I
#43 = Methodref #7.#155 // com/suning/epps/sfeicuss/common/anticoncurrency/PublishAndSubscribe.execute:(Ljava/lang/String;Ljava/lang/Class;ILcom/suning/epps/sfeicuss/common/anticoncurrency/CallBack;)Ljava/lang/Object;
#44 = String #156 // 超过重试次数
#45 = Methodref #26.#157 // com/suning/epps/sfeicuss/common/exception/AppException."<init>":(Ljava/lang/String;)V
#46 = Methodref #158.#159 // org/slf4j/LoggerFactory.getLogger:(Ljava/lang/Class;)Lorg/slf4j/Logger;
#47 = Class #160 // java/lang/Object
#48 = Utf8 InnerClasses
#49 = Utf8 LOGGER
#50 = Utf8 Lorg/slf4j/Logger;
#51 = Utf8 PUBANDSUB_KEY
#52 = Utf8 Ljava/lang/String;
#53 = Utf8 ConstantValue
#54 = Utf8 PUB_KEY
#55 = Utf8 MSG_TRUE
#56 = Utf8 MSG_FALSE
#57 = Utf8 RETRY_TIME
#58 = Utf8 I
#59 = Integer 3
#60 = Utf8 threadLocal
#61 = Utf8 Ljava/lang/ThreadLocal;
#62 = Utf8 Signature
#63 = Utf8 Ljava/lang/ThreadLocal<Ljava/lang/Integer;>;
#64 = Utf8 <init>
#65 = Utf8 ()V
#66 = Utf8 Code
#67 = Utf8 LineNumberTable
#68 = Utf8 LocalVariableTable
#69 = Utf8 this
#70 = Utf8 Lcom/suning/epps/sfeicuss/common/anticoncurrency/PublishAndSubscribe;
#71 = Utf8 execute
#72 = Utf8 (Ljava/lang/String;Ljava/lang/Class;ILcom/suning/epps/sfeicuss/common/anticoncurrency/CallBack;)Ljava/lang/Object;
#73 = Utf8 e
#74 = Utf8 Ljava/lang/Exception;
#75 = Utf8 msg
#76 = Utf8 time
#77 = Utf8 subMsg
#78 = Utf8 key
#79 = Utf8 clazz
#80 = Utf8 Ljava/lang/Class;
#81 = Utf8 retryTime
#82 = Utf8 callBack
#83 = Utf8 Lcom/suning/epps/sfeicuss/common/anticoncurrency/CallBack;
#84 = Utf8 result
#85 = Utf8 Ljava/lang/Object;
#86 = Utf8 pasKey
#87 = Utf8 pubKey
#88 = Utf8 incr
#89 = Utf8 J
#90 = Utf8 flag
#91 = Utf8 Z
#92 = Utf8 LocalVariableTypeTable
#93 = Utf8 Ljava/lang/Class<TT;>;
#94 = Utf8 TT;
#95 = Utf8 StackMapTable
#96 = Class #160 // java/lang/Object
#97 = Class #161 // java/lang/String
#98 = Class #113 // com/suning/epps/sfeicuss/common/anticoncurrency/PublishAndSubscribe
#99 = Class #162 // java/lang/Class
#100 = Class #163 // com/suning/epps/sfeicuss/common/anticoncurrency/CallBack
#101 = Class #133 // java/lang/Exception
#102 = Utf8 <T:Ljava/lang/Object;>(Ljava/lang/String;Ljava/lang/Class<TT;>;ILcom/suning/epps/sfeicuss/common/anticoncurrency/CallBack;)TT;
#103 = Utf8 <clinit>
#104 = Utf8 SourceFile
#105 = Utf8 PublishAndSubscribe.java
#106 = Utf8 RuntimeVisibleAnnotations
#107 = Utf8 Lorg/springframework/stereotype/Service;
#108 = NameAndType #64:#65 // "<init>":()V
#109 = Utf8 com/suning/epps/sfeicuss/common/anticoncurrency/PublishAndSubscribe$1
#110 = NameAndType #64:#164 // "<init>":(Lcom/suning/epps/sfeicuss/common/anticoncurrency/PublishAndSubscribe;)V
#111 = NameAndType #60:#61 // threadLocal:Ljava/lang/ThreadLocal;
#112 = Utf8 java/lang/StringBuilder
#113 = Utf8 com/suning/epps/sfeicuss/common/anticoncurrency/PublishAndSubscribe
#114 = Utf8 PUBANDSUB_KEY_
#115 = NameAndType #165:#166 // append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
#116 = NameAndType #167:#168 // toString:()Ljava/lang/String;
#117 = Class #169 // com/suning/epps/sfeicuss/common/util/RedisClientUtils
#118 = NameAndType #88:#170 // incr:(Ljava/lang/String;)Ljava/lang/Long;
#119 = Class #171 // java/lang/Long
#120 = NameAndType #172:#173 // longValue:()J
#121 = NameAndType #49:#50 // LOGGER:Lorg/slf4j/Logger;
#122 = Utf8 抢占到资源
#123 = Class #174 // org/slf4j/Logger
#124 = NameAndType #175:#176 // debug:(Ljava/lang/String;)V
#125 = Utf8 false
#126 = Class #163 // com/suning/epps/sfeicuss/common/anticoncurrency/CallBack
#127 = NameAndType #177:#178 // process:()Ljava/lang/Object;
#128 = NameAndType #179:#180 // handlerIsSuccessOrNot:(Ljava/lang/Object;)Z
#129 = Utf8 业务结果:{}
#130 = Class #181 // java/lang/Boolean
#131 = NameAndType #182:#183 // valueOf:(Z)Ljava/lang/Boolean;
#132 = NameAndType #175:#184 // debug:(Ljava/lang/String;Ljava/lang/Object;)V
#133 = Utf8 java/lang/Exception
#134 = Utf8 回调业务处理异常
#135 = NameAndType #185:#186 // error:(Ljava/lang/String;Ljava/lang/Throwable;)V
#136 = Utf8 com/suning/epps/sfeicuss/common/exception/AppException
#137 = Class #187 // com/suning/epps/sfeicuss/common/enums/ResponseCode
#138 = NameAndType #188:#189 // ERROR:Lcom/suning/epps/sfeicuss/common/enums/ResponseCode;
#139 = NameAndType #190:#168 // getCode:()Ljava/lang/String;
#140 = NameAndType #64:#191 // "<init>":(Ljava/lang/String;Ljava/lang/String;)V
#141 = NameAndType #192:#193 // putBeanObj:(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/String;
#142 = Utf8 true
#143 = NameAndType #194:#170 // del:(Ljava/lang/String;)Ljava/lang/Long;
#144 = NameAndType #195:#196 // publish:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Long;
#145 = NameAndType #197:#198 // subscribe:(Ljava/lang/String;)Ljava/lang/String;
#146 = Class #161 // java/lang/String
#147 = NameAndType #199:#180 // equals:(Ljava/lang/Object;)Z
#148 = NameAndType #200:#201 // getBeanObj:(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;
#149 = Utf8 收到订阅消息:{}
#150 = NameAndType #202:#203 // handlerResult:(Ljava/lang/Object;)Ljava/lang/Object;
#151 = Class #204 // java/lang/ThreadLocal
#152 = NameAndType #205:#178 // get:()Ljava/lang/Object;
#153 = Utf8 java/lang/Integer
#154 = NameAndType #206:#207 // intValue:()I
#155 = NameAndType #71:#72 // execute:(Ljava/lang/String;Ljava/lang/Class;ILcom/suning/epps/sfeicuss/common/anticoncurrency/CallBack;)Ljava/lang/Object;
#156 = Utf8 超过重试次数
#157 = NameAndType #64:#176 // "<init>":(Ljava/lang/String;)V
#158 = Class #208 // org/slf4j/LoggerFactory
#159 = NameAndType #209:#210 // getLogger:(Ljava/lang/Class;)Lorg/slf4j/Logger;
#160 = Utf8 java/lang/Object
#161 = Utf8 java/lang/String
#162 = Utf8 java/lang/Class
#163 = Utf8 com/suning/epps/sfeicuss/common/anticoncurrency/CallBack
#164 = Utf8 (Lcom/suning/epps/sfeicuss/common/anticoncurrency/PublishAndSubscribe;)V
#165 = Utf8 append
#166 = Utf8 (Ljava/lang/String;)Ljava/lang/StringBuilder;
#167 = Utf8 toString
#168 = Utf8 ()Ljava/lang/String;
#169 = Utf8 com/suning/epps/sfeicuss/common/util/RedisClientUtils
#170 = Utf8 (Ljava/lang/String;)Ljava/lang/Long;
#171 = Utf8 java/lang/Long
#172 = Utf8 longValue
#173 = Utf8 ()J
#174 = Utf8 org/slf4j/Logger
#175 = Utf8 debug
#176 = Utf8 (Ljava/lang/String;)V
#177 = Utf8 process
#178 = Utf8 ()Ljava/lang/Object;
#179 = Utf8 handlerIsSuccessOrNot
#180 = Utf8 (Ljava/lang/Object;)Z
#181 = Utf8 java/lang/Boolean
#182 = Utf8 valueOf
#183 = Utf8 (Z)Ljava/lang/Boolean;
#184 = Utf8 (Ljava/lang/String;Ljava/lang/Object;)V
#185 = Utf8 error
#186 = Utf8 (Ljava/lang/String;Ljava/lang/Throwable;)V
#187 = Utf8 com/suning/epps/sfeicuss/common/enums/ResponseCode
#188 = Utf8 ERROR
#189 = Utf8 Lcom/suning/epps/sfeicuss/common/enums/ResponseCode;
#190 = Utf8 getCode
#191 = Utf8 (Ljava/lang/String;Ljava/lang/String;)V
#192 = Utf8 putBeanObj
#193 = Utf8 (Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/String;
#194 = Utf8 del
#195 = Utf8 publish
#196 = Utf8 (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Long;
#197 = Utf8 subscribe
#198 = Utf8 (Ljava/lang/String;)Ljava/lang/String;
#199 = Utf8 equals
#200 = Utf8 getBeanObj
#201 = Utf8 (Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;
#202 = Utf8 handlerResult
#203 = Utf8 (Ljava/lang/Object;)Ljava/lang/Object;
#204 = Utf8 java/lang/ThreadLocal
#205 = Utf8 get
#206 = Utf8 intValue
#207 = Utf8 ()I
#208 = Utf8 org/slf4j/LoggerFactory
#209 = Utf8 getLogger
#210 = Utf8 (Ljava/lang/Class;)Lorg/slf4j/Logger;
{
public com.suning.epps.sfeicuss.common.anticoncurrency.PublishAndSubscribe();
descriptor: ()V
flags: ACC_PUBLIC
Code:
stack=4, locals=1, args_size=1
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: aload_0
5: new #2 // class com/suning/epps/sfeicuss/common/anticoncurrency/PublishAndSubscribe$1
8: dup
9: aload_0
10: invokespecial #3 // Method com/suning/epps/sfeicuss/common/anticoncurrency/PublishAndSubscribe$1."<init>":(Lcom/suning/epps/sfeicuss/common/anticoncurrency/PublishAndSubscribe;)V
13: putfield #4 // Field threadLocal:Ljava/lang/ThreadLocal;
16: return
LineNumberTable:
line 28: 0
line 60: 4
LocalVariableTable:
Start Length Slot Name Signature
0 17 0 this Lcom/suning/epps/sfeicuss/common/anticoncurrency/PublishAndSubscribe;
public <T extends java.lang.Object> T execute(java.lang.String, java.lang.Class<T>, int, com.suning.epps.sfeicuss.common.anticoncurrency.CallBack);
descriptor: (Ljava/lang/String;Ljava/lang/Class;ILcom/suning/epps/sfeicuss/common/anticoncurrency/CallBack;)Ljava/lang/Object;
flags: ACC_PUBLIC
Code:
stack=5, locals=13, args_size=5
0: aconst_null
1: astore 5
3: new #5 // class java/lang/StringBuilder
6: dup
7: invokespecial #6 // Method java/lang/StringBuilder."<init>":()V
10: ldc #8 // String PUBANDSUB_KEY_
12: invokevirtual #9 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
15: aload_1
16: invokevirtual #9 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
19: invokevirtual #10 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
22: astore 6
24: new #5 // class java/lang/StringBuilder
27: dup
28: invokespecial #6 // Method java/lang/StringBuilder."<init>":()V
31: ldc #11 // String PUB_KEY
33: invokevirtual #9 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
36: aload_1
37: invokevirtual #9 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
40: invokevirtual #10 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
43: astore 7
45: iload_3
46: iconst_1
47: if_icmpge 52
50: iconst_3
51: istore_3
52: aload 6
54: invokestatic #12 // Method com/suning/epps/sfeicuss/common/util/RedisClientUtils.incr:(Ljava/lang/String;)Ljava/lang/Long;
57: invokevirtual #13 // Method java/lang/Long.longValue:()J
60: lstore 8
62: getstatic #14 // Field LOGGER:Lorg/slf4j/Logger;
65: ldc #15 // String 抢占到资源
67: invokeinterface #16, 2 // InterfaceMethod org/slf4j/Logger.debug:(Ljava/lang/String;)V
72: iconst_0
73: istore 10
75: lload 8
77: lconst_1
78: lcmp
79: ifne 195
82: ldc #17 // String false
84: astore 11
86: aload 4
88: invokeinterface #18, 1 // InterfaceMethod com/suning/epps/sfeicuss/common/anticoncurrency/CallBack.process:()Ljava/lang/Object;
93: astore 5
95: aload 4
97: aload 5
99: invokeinterface #19, 2 // InterfaceMethod com/suning/epps/sfeicuss/common/anticoncurrency/CallBack.handlerIsSuccessOrNot:(Ljava/lang/Object;)Z
104: istore 10
106: getstatic #14 // Field LOGGER:Lorg/slf4j/Logger;
109: ldc #20 // String 业务结果:{}
111: iload 10
113: invokestatic #21 // Method java/lang/Boolean.valueOf:(Z)Ljava/lang/Boolean;
116: invokeinterface #22, 3 // InterfaceMethod org/slf4j/Logger.debug:(Ljava/lang/String;Ljava/lang/Object;)V
121: goto 154
124: astore 12
126: getstatic #14 // Field LOGGER:Lorg/slf4j/Logger;
129: ldc #24 // String 回调业务处理异常
131: aload 12
133: invokeinterface #25, 3 // InterfaceMethod org/slf4j/Logger.error:(Ljava/lang/String;Ljava/lang/Throwable;)V
138: new #26 // class com/suning/epps/sfeicuss/common/exception/AppException
141: dup
142: ldc #24 // String 回调业务处理异常
144: getstatic #27 // Field com/suning/epps/sfeicuss/common/enums/ResponseCode.ERROR:Lcom/suning/epps/sfeicuss/common/enums/ResponseCode;
147: invokevirtual #28 // Method com/suning/epps/sfeicuss/common/enums/ResponseCode.getCode:()Ljava/lang/String;
150: invokespecial #29 // Method com/suning/epps/sfeicuss/common/exception/AppException."<init>":(Ljava/lang/String;Ljava/lang/String;)V
153: athrow
154: iload 10
156: ifeq 171
159: aload 7
161: aload 5
163: invokestatic #30 // Method com/suning/epps/sfeicuss/common/util/RedisClientUtils.putBeanObj:(Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/String;
166: pop
167: ldc #31 // String true
169: astore 11
171: aload 6
173: invokestatic #32 // Method com/suning/epps/sfeicuss/common/util/RedisClientUtils.del:(Ljava/lang/String;)Ljava/lang/Long;
176: invokevirtual #13 // Method java/lang/Long.longValue:()J
179: lconst_1
180: lcmp
181: ifne 192
184: aload 6
186: aload 11
188: invokestatic #33 // Method com/suning/epps/sfeicuss/common/util/RedisClientUtils.publish:(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Long;
191: pop
192: aload 5
194: areturn
195: aload 6
197: invokestatic #34 // Method com/suning/epps/sfeicuss/common/util/RedisClientUtils.subscribe:(Ljava/lang/String;)Ljava/lang/String;
200: astore 11
202: getstatic #14 // Field LOGGER:Lorg/slf4j/Logger;
205: ldc #35 // String subMsg
207: aload 11
209: invokeinterface #22, 3 // InterfaceMethod org/slf4j/Logger.debug:(Ljava/lang/String;Ljava/lang/Object;)V
214: ldc #31 // String true
216: aload 11
218: invokevirtual #36 // Method java/lang/String.equals:(Ljava/lang/Object;)Z
221: ifeq 254
224: aload 7
226: aload_2
227: invokestatic #37 // Method com/suning/epps/sfeicuss/common/util/RedisClientUtils.getBeanObj:(Ljava/lang/String;Ljava/lang/Class;)Ljava/lang/Object;
230: astore 5
232: getstatic #14 // Field LOGGER:Lorg/slf4j/Logger;
235: ldc #38 // String 收到订阅消息:{}
237: aload 5
239: invokeinterface #22, 3 // InterfaceMethod org/slf4j/Logger.debug:(Ljava/lang/String;Ljava/lang/Object;)V
244: aload 4
246: aload 5
248: invokeinterface #39, 2 // InterfaceMethod com/suning/epps/sfeicuss/common/anticoncurrency/CallBack.handlerResult:(Ljava/lang/Object;)Ljava/lang/Object;
253: areturn
254: aload_0
255: getfield #4 // Field threadLocal:Ljava/lang/ThreadLocal;
258: invokevirtual #40 // Method java/lang/ThreadLocal.get:()Ljava/lang/Object;
261: checkcast #41 // class java/lang/Integer
264: invokevirtual #42 // Method java/lang/Integer.intValue:()I
267: istore 12
269: iload 12
271: iload_3
272: if_icmpge 288
275: iinc 12, 1
278: aload_0
279: aload_1
280: aload_2
281: iload_3
282: aload 4
284: invokevirtual #43 // Method execute:(Ljava/lang/String;Ljava/lang/Class;ILcom/suning/epps/sfeicuss/common/anticoncurrency/CallBack;)Ljava/lang/Object;
287: areturn
288: new #26 // class com/suning/epps/sfeicuss/common/exception/AppException
291: dup
292: ldc #44 // String 超过重试次数
294: invokespecial #45 // Method com/suning/epps/sfeicuss/common/exception/AppException."<init>":(Ljava/lang/String;)V
297: athrow
Exception table:
from to target type
86 121 124 Class java/lang/Exception
LineNumberTable:
line 78: 0
line 79: 3
line 80: 24
line 81: 45
line 83: 50
line 86: 52
line 87: 62
line 88: 72
line 89: 75
line 90: 82
line 93: 86
line 94: 95
line 95: 106
line 99: 121
line 96: 124
line 97: 126
line 98: 138
line 100: 154
line 102: 159
line 103: 167
line 105: 171
line 106: 184
line 108: 192
line 110: 195
line 111: 202
line 112: 214
line 113: 224
line 114: 232
line 115: 244
line 119: 254
line 120: 269
line 121: 275
line 122: 278
line 124: 288
LocalVariableTable:
Start Length Slot Name Signature
126 28 12 e Ljava/lang/Exception;
86 109 11 msg Ljava/lang/String;
269 29 12 time I
202 96 11 subMsg Ljava/lang/String;
0 298 0 this Lcom/suning/epps/sfeicuss/common/anticoncurrency/PublishAndSubscribe;
0 298 1 key Ljava/lang/String;
0 298 2 clazz Ljava/lang/Class;
0 298 3 retryTime I
0 298 4 callBack Lcom/suning/epps/sfeicuss/common/anticoncurrency/CallBack;
3 295 5 result Ljava/lang/Object;
24 274 6 pasKey Ljava/lang/String;
45 253 7 pubKey Ljava/lang/String;
62 236 8 incr J
75 223 10 flag Z
LocalVariableTypeTable:
Start Length Slot Name Signature
0 298 2 clazz Ljava/lang/Class<TT;>;
3 295 5 result TT;
StackMapTable: number_of_entries = 8
frame_type = 254 /* append */
offset_delta = 52
locals = [ class java/lang/Object, class java/lang/String, class java/lang/String ] frame_type = 255 /* full_frame */ offset_delta = 71 locals = [ class com/suning/epps/sfeicuss/common/anticoncurrency/PublishAndSubscribe, class java/lang/String, class java/lang/Class, int, class com/suning/epps/sfeicuss/common/anticoncurrency/CallBack, class java/lang/Object, class java/lang/String, class java/lang/String, long, int, class java/lang/String ] stack = [ class java/lang/Exception ] frame_type = 29 /* same */ frame_type = 16 /* same */ frame_type = 20 /* same */ frame_type = 250 /* chop */ offset_delta = 2 frame_type = 252 /* append */ offset_delta = 58 locals = [ class java/lang/String ] frame_type = 252 /* append */ offset_delta = 33 locals = [ int ] Signature: #102 // <T:Ljava/lang/Object;>(Ljava/lang/String;Ljava/lang/Class<TT;>;ILcom/suning/epps/sfeicuss/common/anticoncurrency/CallBack;)TT; static {}; descriptor: ()V flags: ACC_STATIC Code: stack=1, locals=0, args_size=0 0: ldc #7 // class com/suning/epps/sfeicuss/common/anticoncurrency/PublishAndSubscribe 2: invokestatic #46 // Method org/slf4j/LoggerFactory.getLogger:(Ljava/lang/Class;)Lorg/slf4j/Logger; 5: putstatic #14 // Field LOGGER:Lorg/slf4j/Logger; 8: return LineNumberTable: line 30: 0 } SourceFile: "PublishAndSubscribe.java" RuntimeVisibleAnnotations: 0: #107() InnerClasses: #2; //class com/suning/epps/sfeicuss/common/anticoncurrency/PublishAndSubscribe$1