当前位置: 首页 > 科技观察

好像总是记不住字节取值范围是-127~128还是-128~127

时间:2023-03-16 10:06:33 科技观察

1.前言无论是在面试过程中,还是在平时的技术交流中,看来很多朋友还是可以的'记得java中byte类型的取值范围是多少。原因是大部分程序员并不关心这个取值范围,因为知道或不知道都不会影响你的工作。另外,这种知识点根本不是让你死记硬背的。当然,如果你是从其他文科专业转过来学习编程和开发的,也是无可厚非的。但是对于理科学生来说,不应该。2、取值范围的计算在java中byte占1个字节8位,可以想象成8个小块的数据区间,第1位为0、1代表符号位。**0[positive],1[negative]**,然后绘制表格如下;字节数876543212?2^72^62^52^42^32^22^12^0值1286432168421+12701111111-12810000000+127二进制和2^0+2^1+2^2+2^3+2^4+2^5+2^6+2^7=2^(n+1)-1=127-128二进制和2^8=128好了,现在你明白逻辑了很清楚了,负数为什么要到-128,因为1代表负数的符号位,正好是2的8次方,-128。3、十六进制值转换由于Java语言中字节的取值范围与其他一些语言不同,所以在处理一些文件时有时需要进行十六进制转换。即-128~127和0~255的转换处理;比如我们现在将java中的一个byte=120转换成0~255范围内的值;一般情况下,可以进行AND运算;120&0x0FF也可以同时递增位操作;(也就是把8字节长度的内容变成16长度再转换)byte[]val={-120};BigIntegerbigInteger=newBigInteger(1,val);//有符号System.out.println(bigInteger.byteValue());//无符号(自增)Stringstr_hex=bigInteger.toString(16);System.out.println(Integer.parseInt(str_hex,16));//136四、分析一段class字节码Java类文件会被编译成class文件,然后class文件需要经过jvm的解析、校验、加载等,才能被虚拟机指令执行。如果下面是一个class文件的字节数组,解析其中的内容得到对应的结果;publicclassClassReaderTest{//获取部分字节码:java.lang.Stringprivatestaticbyte[]classData={-54,-2,-70,-66,0,0,0,52,2,26,3,0,0,-40,0,3,0,0,-37,-1,3,0,0,-33,-1,3,0,1,0,0,8,0,59,8,0,83,8,0,86,8,0,87,8,0,110,8,0,-83,8,0,-77,8,0,-49,8,0,-47,1,0,3,40,41,73,1,0,20,40,41,76,106,97,118,97,47,108,97,110,103,47,79,98,106,101,99,116,59,1,0,20,40,41,76,106,97,118,97,47,108,97,110,103,47,83,116,114,105,110,103,59,1,0,3,40,41,86,1,0,3,40,41,90,1,0,4,40,41,91,66,1,0,4,40,41,91,67,1,0,4,40,67,41,67,1,0,21,40,68,41,76,106,97,118,97,47,108,97,110,103,47,83,116,114,105,110,103,59,1,0,4,40,73,41,67,1,0,4};publicstaticvoidmain(String[]args){//classData是我们的字节码,第一个是-54,因为byte的值范围是-128~+127,所以如果想看到和其他虚拟机一样的值,需要在行后进行AND运算System.out.println("*bytecodeandoperationoriginalvalue(-54)中断(-54&0x0FF):"+(-54&0x0FF));//检查幻数readAndCheckMagic();//查看版本号readAndCheckVersion();//然后依次读取[可以参考java版虚拟机代码];constantPool,accessFlags,thisClassIdx,supperClassIdx,interfaces,fields,methods,attributes}/***检查幻数*

*很多文件格式规定满足这种格式的文件必须以一定的固定字节开头,这几个字节主要起到角色识别,称为幻数(magicnumber)。*例如;*PDF文件以4个字节“%PDF”(0x25、0x50、0x44、0x46)开头,*ZIP文件以2个字节“PK”(0x50、0x4B)开头*类文件以4个字节“0xCAFEBABE”开头*/privatestaticvoidreadAndCheckMagic(){System.out.println("\r\n------------检查幻数------------");//从类bytecode[]中读取前四个字节magic_byte=newbyte[4];System.arraycopy(classData,0,magic_byte,0,4);//合并4个字节转换为十六进制字符串Stringmagic_hex_str=newBigInteger(1,magic_byte).toString(16);System.out.println("magic_hex_str:"+magic_hex_str);//byte_magic_str是16进制的字符串,cafebabe,因为java中没有无符号整型,如果想无符号只能放在高位longmagic_unsigned_int32=Long.parseLong(magic_hex_str,16);System.out.println("magic_unsigned_int32:"+magic_unsigned_int32);//幻数比较,一种是字符串比较,一种是使用假设的无符号十六进制比较。如果使用无符号比较,则需要将0xCAFEBABE&0x0FFFFFFFFFL与操作结合System.out.println("0xCAFEBABE&0x0FFFFFFFFFL:"+(0xCAFEBABE&0x0FFFFFFFFFL));if(magic_unsigned_int32==(0xCAFEBABE&0x0FFFFFFFFFL)){System.out.println("类字节码幻数无符号十六进制值一致性验证通过");}else{System.out.println("类字节码幻数无符号十六进制值一致性验证被拒绝");}}/***验证版本号*

*magicnumber后面是class文件的次版本号和主版本号,都是u2类型。假设一个类文件的主版本号为M,次版本号为m,那么完整的版本号可以用“M.m”的形式表示。次要版本号在J2SE1.2之前才用过,1.2以后基本没用了(全0)。J2SE1.2之前的主要版本号是45。*从1.2开始,每发布一个Java大版本,都会加1{45,46,47,48,49,50,51,52}*/privatestaticvoidreadAndCheckVersion(){System.out.println("\r\n------------检查版本号------------");//从class字节码的第4位开始读取,读取2位byte[]minor_byte=newbyte[2];System.arraycopy(classData,4,minor_byte,0,2);//将2个字节转为十六进制字符串Stringminor_hex_str=newBigInteger(1,minor_byte).toString(16);System.out.println("minor_hex_str:"+minor_hex_str);//minor_unsigned_int32转换为无符号十六进制intminor_unsigned_int32=Integer.parseInt(minor_hex_str,16);System.out.println("minor_unsigned_int32:"+minor_unsigned_int32);//从类字节码的第6位开始读取,读取2位byte[]major_byte=newbyte[2];System.arraycopy(classData,6,major_byte,0,2);//将2个字节转成十六进制字符串Stringmajor_hex_str=newBigInteger(1,major_byte).toString(16);系统输出。println("major_hex_str:"+major_hex_str);//major_unsigned_int32转换为无符号十六进制intmajor_unsigned_int32=Integer.parseInt(major_hex_str,16);System.out.println("major_unsigned_int32:"+major_unsigned_int32);System.out.println("版本号:"+major_unsigned_int32+"."+minor_unsigned_int32);}}测试结果:*Byte字节码与运算原值(-54)换行后(-54&0x0FF):202------------验证幻数-----------magic_hex_str:cafebabemagic_unsigned_int32:34056915820xCAFEBABE&0x0FFFFFFFFFL:3405691582类字节码幻数无符号十六进制值一致性验证通过------------验证版本号-------------minor_hex_str:0minor_unsigned_int32:0major_hex_str:34major_unsigned_int32:52versionnumber:52.0Processfinishedwithexitcode05.总结关于byte的文章;《用java实现jvm虚拟机》书里有提到,但是没有单独分析。现单独分析,以加强对任何一个可能不起眼的知识点的记忆。不是它不重要,而是你还没有用过。俗话说,不是读书没用,而是你没用。普通话博大精深!认真对待每一个知识点,不断夯实自己的地基,就像盖房子打地基一样。你越深入、越稳定,上层结构就越精致,最终就能服从你。

最新推荐
猜你喜欢