【Java学习】调用ByteBuffer.getInt()方法得到808464432
调用ByteBuffer.getInt()方法遇到的奇怪错误
最近在参加阿里的中间件比赛,中间用到了RocketMQ的思想,并且主要集中在使用NIO来读写文件。其中遇到了一个很蛋疼的问题,想了半天想不出来为什么,现已解决并来记录一下。
先上代码:
@Test
public void test() throws IOException {
FileChannel fc = new RandomAccessFile(STORE_PATH, "rw").getChannel();
ByteBuffer byteBuffer = fc.map(FileChannel.MapMode.READ_WRITE, 0, 1024);
int a = byteBuffer.getInt();
System.out.println(a);
}
代码主要使用了Java NIO中的FileChannel和ByteBuffer,目的是读取文件中的四个字节,并将其转为int类型的数字,对于这个文件我手动输入了四个'0',按照我的想法,读出来应该还是会为0。然而结果却如下:

808464432
这是个什么鬼?试了几次都是一样的数字,觉得很奇怪,为什么不是0呢。看了下ByteBuffer.getInt()的源码,发现ByteBuffer是一个抽象类,该方法有两种实现方式,分别是DirectByteBuffer和HeapByteBuffer,其中NIO使用的DirectByteBuffer,所以看下源码:
private int getInt(long a) {
if (unaligned) {
int x = unsafe.getInt(a);
return (nativeByteOrder ? x : Bits.swap(x));
}
return Bits.getInt(a, bigEndian);
}
public int getInt() {
return getInt(ix(nextGetIndex((1 << 2))));
}
其中调用的是Unsafe包下的getInt()的native方法,好像又遇到死胡同了。
最后没招了,突发奇想搜了一下808464432这个数字,搜到
int变量的值为808464432 是为什么?内存越界?被赋错值?这篇博客,其中的一段话很明确的解释了原因:
808464432,是10进制数,转换为16进制是0x30303030,0x30是字符'0'的ASCII码的16进制表示,也就是说,808464432这个数字,对应字符串“0000”,一个int变量,占4个字节,如果每个字节都写入一个字符'0',那么就会是这个数。
原来是因为我输入的时候是以字符形式输入到文件,稍微修改一下代码,果然就好了,代码和结果如下:
@Test
public void test() throws IOException {
FileChannel fc = new RandomAccessFile(STORE_PATH, "rw").getChannel();
ByteBuffer byteBuffer = fc.map(FileChannel.MapMode.READ_WRITE, 0, 1024);
byteBuffer.putInt(0,1);
int a = byteBuffer.getInt();
System.out.println(a);
}

【Java学习】调用ByteBuffer.getInt()方法得到808464432的更多相关文章
- Java学习-026-类名或方法名应用之二 -- 统计分析基础
前文讲述了类名或方法的应用之一调试源码,具体请参阅:Java学习-025-类名或方法名应用之一 -- 调试源码 此文主要讲述类名或方法应用之二统计分析,通过在各个方法中插桩(调用桩方法),获取方法的调 ...
- Java学习-025-类名或方法名应用之一 -- 调试源码
上文讲述了如何获取类名和方法名,敬请参阅: Java学习-024-获取当前类名或方法名二三文 . 通常在应用开发中,调试或查看是哪个文件中的方法调用了当前文件的此方法,因而在实际的应用中需要获取相应的 ...
- JAVA如何调用C/C++方法
JAVA如何调用C/C++方法 2013-05-27 JAVA以其跨平台的特性深受人们喜爱,而又正由于它的跨平台的目的,使得它和本地机器的各种内部联系变得很少,约束了它的功能.解决JAVA对本地操作的 ...
- java学习笔记5--类的方法
接着前面的学习: java学习笔记4--类与对象的基本概念(2) java学习笔记3--类与对象的基本概念(1) java学习笔记2--数据类型.数组 java学习笔记1--开发环境平台总结 本文地址 ...
- java学习之创建线程方法二
我们上一节当中讲到了创建线程的第一种方法,就是继承Thread类,覆写Thread当中的run方法,然后创建子类对象,之后调用对象的start方法启动线程.但是这种方法有一个缺陷,因为我们知道在jav ...
- Java动态调用类中方法
在Java中,调用类的方法有两种方式:对于静态方法可以直接使用类名调用,对于非静态方法必须使用类的对象调用.反射机制提供了比较另类的调用方式,可以根据需要指定要调用的方法,而不必在编程时确定.调用的方 ...
- 【Android】java中调用JS的方法
最近因为学校换了新的教务系统,想做一个模拟登陆功能,发现登陆的账号和密码有一个js脚本来进行加密 整理了一下java中执行JS的方法 智强教务 账号 密码 加密方法 var keyStr = &quo ...
- Java学习笔记4(方法)
方法和c++中的函数类似,区别在于java的方法定义不限位置,而c++中的定义在主函数后面的函数调用前要声明: 求矩形面积方法示例: public class MethodDemo{ public s ...
- Java学习之==>常用字符串方法
1.定义字符串 // 定义, 为初始化 String str1; // 定义, 并初始化为null String str2 = null; // 定义, 并初始化为空串 String str3 = & ...
随机推荐
- HDU 2588 思维 容斥
求满足$1<=X<=N ,(X,N)>=M$的个数,其中$N, M (2<=N<=1000000000, 1<=M<=N)$. 首先,假定$(x, n)=m$ ...
- .net core 中 Identity Server 4 Topic 之 Startup
约定 简称 Id4. Id4在.net core 中的使用符合.net core 的约定架构,即Services来注册服务,middleware方式集成. 1. 配置服务 通过DI注入: public ...
- [acmm week12]染色(容斥定理+组合数+逆元)
1003 染色 Time Limit: 1sec Memory Limit:256MB Description 今天离散数学课学了有关树的知识,god_v是个喜欢画画的人,所以他 ...
- 【BZOJ】4766: 文艺计算姬
[题目]给定两边节点数为n和m的完全二分图,求生成树数取模给定的p.n,m,p<=10^18. [算法]生成树计数(矩阵树定理) [题解]参考自 [bzoj4766]文艺计算姬 by WerKe ...
- Windows.event
获取鼠标位置 document.getElementById('div').onmousemove = function(e){ //--------Chrome, firefox 支持------- ...
- mybatis错误总结
1:传递多个参数失败 Parameter 'username' not found. Available parameters are [0, 1, param1, param2] dao层错误写 ...
- 五. Jmeter--HTTP Cookie Manager
1. 添加HTTP Cookie Manager 2.添加登录login http,request info 和 HTTP Header Manager 中的信息是从fiddler中拿的, 至于hea ...
- Linux下帮助命令
帮助命令(各种命令区别) 最常用的帮助命令 help --help help cd 查看内置命令的使用 info man help cd 查看内置命令的使用 获得帮助的途径: ma ...
- shell脚本执行方式
# BY THE WAY, 其实这块内容算是比较简单的,但是都比较常记得它最基本的两种方式,另外两种却忘记了 1. 利用sh或bash命令执行 sh test.sh bash test.sh 2. 在 ...
- laravel入门教程
参考地址:https://github.com/johnlui/Learn-Laravel-5/issues/16