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) <<
|
(b[index + 3]
& 0xFF);
}
public short readShort (final int index) {
byte[] b = this.b;
return (short)(((b[index]
& 0xFF) <<
| (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) <<
|
(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:
代码
- int result=0;
- int tmp=b[index];
- tmp=tmp<<24;
- tmp=tmpclass=hilite1>&0xFF000000;
- result=result+tmp;
- tmp=b[index+1];
- tmp=tmp<<16;
- tmp=tmpclass=hilite1>&0x00FF0000;
- result=result+tmp;
- tmp=b[index+2];
- tmp=tmp<<8;
- tmp=tmpclass=hilite1>&0x0000FF00;
- result=result+tmp;
- tmp=b[index+3];
- tmp=tmpclass=hilite1>&0x000000FF;
- result=result+tmp;
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;
同意否?
------------------------------------------------------------------------------------------------------------------------------------------
riss:
这里很明显,tmp就是整形变量,byte转向int类型是理所当然的。
在这里,b[index]
&0xFF完全可在存储在一个字节的大小的区域里(8bit)那么现在就是说为什么它知道强制放在4字节的区域里(int:32bit).(把tmp改为byte类型照常工作,只是结果不正确罢了!).再对比,readShort和readLong,这个说法好像是说不过去。
------------------------------------------------------------------------------------------------------------------------------------------
zgli:
java 的位运算符最小工作在int下啊,这好象是规定
代码
- byte a=23;
- byte b=a class=hilite1>& class=hilite2>0xFF;
byte a=23;
byte b=a & 0xFF;
在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不知天天在想些什么?也许是我误解,但是还是想了解一下是怎么个回事?