调用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的更多相关文章

  1. Java学习-026-类名或方法名应用之二 -- 统计分析基础

    前文讲述了类名或方法的应用之一调试源码,具体请参阅:Java学习-025-类名或方法名应用之一 -- 调试源码 此文主要讲述类名或方法应用之二统计分析,通过在各个方法中插桩(调用桩方法),获取方法的调 ...

  2. Java学习-025-类名或方法名应用之一 -- 调试源码

    上文讲述了如何获取类名和方法名,敬请参阅: Java学习-024-获取当前类名或方法名二三文 . 通常在应用开发中,调试或查看是哪个文件中的方法调用了当前文件的此方法,因而在实际的应用中需要获取相应的 ...

  3. JAVA如何调用C/C++方法

    JAVA如何调用C/C++方法 2013-05-27 JAVA以其跨平台的特性深受人们喜爱,而又正由于它的跨平台的目的,使得它和本地机器的各种内部联系变得很少,约束了它的功能.解决JAVA对本地操作的 ...

  4. java学习笔记5--类的方法

    接着前面的学习: java学习笔记4--类与对象的基本概念(2) java学习笔记3--类与对象的基本概念(1) java学习笔记2--数据类型.数组 java学习笔记1--开发环境平台总结 本文地址 ...

  5. java学习之创建线程方法二

    我们上一节当中讲到了创建线程的第一种方法,就是继承Thread类,覆写Thread当中的run方法,然后创建子类对象,之后调用对象的start方法启动线程.但是这种方法有一个缺陷,因为我们知道在jav ...

  6. Java动态调用类中方法

    在Java中,调用类的方法有两种方式:对于静态方法可以直接使用类名调用,对于非静态方法必须使用类的对象调用.反射机制提供了比较另类的调用方式,可以根据需要指定要调用的方法,而不必在编程时确定.调用的方 ...

  7. 【Android】java中调用JS的方法

    最近因为学校换了新的教务系统,想做一个模拟登陆功能,发现登陆的账号和密码有一个js脚本来进行加密 整理了一下java中执行JS的方法 智强教务 账号 密码 加密方法 var keyStr = &quo ...

  8. Java学习笔记4(方法)

    方法和c++中的函数类似,区别在于java的方法定义不限位置,而c++中的定义在主函数后面的函数调用前要声明: 求矩形面积方法示例: public class MethodDemo{ public s ...

  9. Java学习之==>常用字符串方法

    1.定义字符串 // 定义, 为初始化 String str1; // 定义, 并初始化为null String str2 = null; // 定义, 并初始化为空串 String str3 = & ...

随机推荐

  1. 不管谁坐了CIO的位置 都必须了解的法则

    目前一些设立了CIO岗位的央企中,CIO也只做到了“IO”(信息官,Information Officer),而没有做到“C”(首席,Chief).老总们总在抱怨没有合适的人选:懂技术的不懂业务,懂业 ...

  2. 如何在AngularJS渲染后再加载JS

    http://www.itnose.net/detail/6100484.html app.directive('repeatDone', function () { return function ...

  3. ③ 设计模式的艺术-09.组合(Composite)模式

    使用组合模式的场景 类图当中有三个类,一个是Component(节点的统一接口),它的目的是为了统一节点的操作.接下来的两个实现类,一个则是非叶子节点(Composite),它可以有子节点.另外一个则 ...

  4. SpringCloud入门系列(一)

    https://www.cnblogs.com/edisonchou/p/java_spring_cloud_foundation_sample_list.html

  5. 【BZOJ】2125: 最短路 圆方树(静态仙人掌)

    [题意]给定带边权仙人掌图,Q次询问两点间最短距离.n,m,Q<=10000 [算法]圆方树处理仙人掌问题 [题解]树上的两点间最短路问题,常用倍增求LCA解决,考虑扩展到仙人掌图. 先对仙人掌 ...

  6. jQuery.Event的一些用法

    直接写用法 //创建一个事件 var event = $.Event("事件类型",["定义的事件参数最终将出现在e1中"]); //绑定一个处理器 $(obj ...

  7. Linux下命令lrzsz

    lrzsz是什么 在使用Linux的过程中,难免少不了需要上传下载文件,比如往服务器上传一些war包之类的,之前都是使用winSCP,lrzsz是一个更方便的命令,可以直接在Linux中输入命令,弹出 ...

  8. 【译】第三篇 SQL Server代理警报和操作员

    本篇文章是SQL Server代理系列的第三篇,详细内容请参考原文. 正如这一系列的上一篇所述,SQL Server代理作业是由一系列的作业步骤组成,每个步骤由一个独立的类型去执行,除了步骤中执行的工 ...

  9. Balanced and stabilized quicksort method

    The improved Quicksort method of the present invention utilizes two pointers initialized at opposite ...

  10. linux设备驱动模型-浅析-转

    1.  typeof typeof并非ISO C的关键字,而是gcc对C的一个扩展.typeof是一个关键字(类似sizeof),用于获取一个表达式的类型. 举个简单的例子: char tt; typ ...