关于ASM中版本号定义的疑问

在asm的源码中看到Opcodes类文件中,有这么一段,定义了java class文件的版本号:

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;

中间涉及到java的位运算的操作,学习java以来,对位运算一直处于半瓶子的状态,正好借着这个机会,认真学习下。
java的位运算操作符包含:


&(and),~(not),^(xor),|(or),>>(右移),>>>(无符号右移),<<(左移)


上面的java代码中主要用到了[<<左移操作符]和[|或]操作符。左移操作符功能把“<<”左边的运算数的各二进位全部左移若干位,由“ < <”右边的数指定移动的位数, 高位丢弃,低位补0.如 3 << 4,3对应的二进制表达式为:00000011,那么左移4位为:00110000(十进制为48).
而“|”操作符,是将|两边的数值进行或值进行运算,只要两边的任意一方是1那么,那么结果就为1.如: 0 | 10 = 0 | 1010 = 1010 = 10; 0与任意数进行相或运算,结果都是另一边的数值。
接下来先看下上面的代码中的[b]V1_2至V1_7[/b],0 << 16,将0向左移16位,还是0,那么0再与右边的数字想或,那么结果就还是右边的的数值。如V1_2 = 46,V1_3=47以此类推。而V1_1先是 3<<16,我算了下是196608,再与45相或那么是196653,版本号有这么大么?我表示怀疑。上网查了下jdk1.1生成的版本号是45.3,其中45是主版本号,而3是次版本号。那为什么是196608这个数值呢?
于是我开始下面的实验:
用命令javac -target 1.1 Example.java文件,生成的class文件,用十六进制编辑器打开class文件:
根据class文件的结构,开头是魔数,后面是次版本号+主版本号,为0003002D的十六进制。将V1_1的数值用16进制表示发现:

String s = Integer.toHexString(V1_1);
System.out.println(s); //输出3002d

输出的字符串正好是class文件中16进制表示的字符串,所以说asm并没有错误。
asm通过将十六进制的主版本号和次版本号一起作为一个int数值进行读取,所有才有上面看
似不正确的版本数值。至于为什么用位运算来写,我想可能有以下原因:
1.位运算的操作速度更快(这个并没有什么提高或者变慢,因为编译后,用javap查看,发现已变成数值常量)
2.修改jdk的主版本号或者次版本号更方便。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值