一些函数:从字节码中提取某种类型的值

riss:
下面这些函数从字节码中提取对应类型的值:


代码

//this.b是字节码数组
public int readInt (final int index) {
byte[] b = this.b;
return ((b[index] & 0xFF) << 24) |
((b[index + 1] & 0xFF) << 16) |
((b[index + 2] & 0xFF) << 8) |
(b[index + 3] & 0xFF);
}

public short readShort (final int index) {
byte[] b = this.b;
return (short)(((b[index] & 0xFF) << 8) | (b[index + 1] & 0xFF));
}

public long readLong (final int index) {
long l1 = readInt(index);
long l0 = readInt(index + 4) & 0xFFFFFFFFL;
return (l1 << 32) | l0;
}
.......

就拿readInt来说:

代码
public int readInt (final int index) {
byte[] b = this.b;
return ((b[index] & 0xFF) << 24) |
((b[index + 1] & 0xFF) << 16) |
((b[index + 2] & 0xFF) << 8) |
(b[index + 3] & 0xFF);
}
问题1:b[index]&0xFF有啥意义(11100111&11111111=11100111)与0xFF不是多此一举吗?

问题2:
第一种理解(还算说的过去):(b[index] & 0xFF) << 24,(11100111<<24=00000000)这里要说的是左移24位--根据我的理解--b[index] & 0xFF的结果首先放入一个整形变量中(应该说是压入这个方法的栈帧中),左移24位就放在最高的一个字节,这样就得到这个整形值的最高的一个字节(XXXXXXXXXXXXXXXXXXXXXXXX11100111<<24=11100111000000000000000000000000),依次类推(左移16,8,0位)后把他们的值相"或"就可以得到一个完整的整形值并放入retrunaddress指向的区域.
第二种理解(说不过去):b[index] 是字节类型,那么b[index] & 0xFF结果类型该是字节类型,左移24位等于什么(00000000),所以让我疑惑的是JVM怎么知道把(b[index] & 0xFF)的结果放入一个整形大小的区域呢?

问题3:此问题与主题不相关,在<深入Java虚拟机>中说到可以(按它说的)得到版本号,可我把我的类文件打开看这些字节确是"0000 002E",如何解释?

那位兄弟可以帮我解开这个迷团,谢谢!
------------------------------------------------------------------------------------------------------------------------------------------
zgli:

代码
[code]
int result=0;
int tmp=b[index];
tmp=tmp<<24;
tmp=tmp&0xFF000000;
result=result+tmp;
tmp=b[index+1];
tmp=tmp<<16;
tmp=tmp&0x00FF0000;
result=result+tmp;
tmp=b[index+2];
tmp=tmp<<8;
tmp=tmp&0x0000FF00;
result=result+tmp;
tmp=b[index+3];
tmp=tmp&0x000000FF;
result=result+tmp;
[/code]
同意否?

------------------------------------------------------------------------------------------------------------------------------------------
riss:
这里很明显,tmp就是整形变量,byte转向int类型是理所当然的。
在这里,b[index]&0xFF完全可在存储在一个字节的大小的区域里(8bit)那么现在就是说为什么它知道强制放在4字节的区域里(int:32bit).(把tmp改为byte类型照常工作,只是结果不正确罢了!).再对比,readShort和readLong,这个说法好像是说不过去。
------------------------------------------------------------------------------------------------------------------------------------------
zgli:
java 的位运算符最小工作在int下啊,这好象是规定


代码
[code]
byte a=23;
byte b=a & 0xFF;
[/code]

在eclipse下提示:Type mismatch: cannot convert from int to byte

说明 a & 0xFF 的结果是整数

其他的问题也就不用说的

有了这个结论另两个就合理了

------------------------------------------------------------------------------------------------------------------------------------------
dwangel:
因为0xff是整型,
byte[] aa;

aa[index] & 0xff 向大的数据类型靠拢,就是整型了。

------------------------------------------------------------------------------------------------------------------------------------------
dazuiba:
1 .java中的byte 是sign的
2 所以 将一个负byte强制转换成int,就会损坏原来的binary表示,例如:
byte bb=(byte) 0xf1; //11110001
printBinary((int)bb);//11111111111111111111111111110001
所以要用0xff操作一下, readInt(index + 4) & 0xFFFFFFFF; 同样的道理
3 因为2,所以你程序中的第一个byte可以强制转换为int,而结果不会收到影响
4 要转为int的原因是你的返回值是int,而不是因为jvm默认int.
-----------------------------------------
------------------------------------------------------------------------------------------------------------------------------------------
riss:
看了这么多,终于明白了,谢谢各位的帮忙。
基础不扎实,学的全还给老师了。

那么问题3,对于明白的该不是什么问题吧!只是看书上的好像不正确,是不是Java更新换代了,这个的解析方法也变了?

再次感谢!谢谢!

------------------------------------------------------------------------------------------------------------------------------------------
riss:
问题3已经解决。但是想不明白,为什么要这样规定:
1.1的前面两字节是3而1.2以后的版本都是0。这个谁可以解释来听听啊!想不通!要不一真沿用3,要不一开始就弄成0不好吗?
什么乱七八糟的!sun不知天天在想些什么?也许是我误解,但是还是想了解一下是怎么个回事?
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值