论坛首页 Java企业应用论坛

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

浏览 1720 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (11) :: 隐藏帖 (0)
作者 正文
   发表时间:2011-02-09   最后修改:2011-02-11
在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与任意数进行相或运算,结果都是另一边的数值。
    接下来先看下上面的代码中的V1_2至V1_7,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的主版本号或者次版本号更方便。
   发表时间:2011-02-09  
没有更快或者更慢。

编译后,上面代码每句的右边都是常数了。
0 请登录后投票
   发表时间:2011-02-09  
kimmking 写道
没有更快或者更慢。

编译后,上面代码每句的右边都是常数了。


用javap -verbose查看了下,是变成一个int型的常量了,没有什么速度上的提高。谢谢指正。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics