《Java源码分析》:Java NIO 之 Buffer

本文详细分析了Java NIO Buffer的源码,涵盖了Buffer的重要属性如capacity、limit和position,以及allocate、put、get、flip、hasRemaining、clear和compact等关键方法的工作原理。通过源码阅读,帮助读者理解Buffer在读写模式下的行为。
摘要由CSDN通过智能技术生成

《Java源码分析》:Java NIO 之 Buffer

在上篇博文中,我们介绍了Java NIO 中Channel 和Buffer的基本使用方法,这篇博文将从源码的角度来看下Buffer的内部实现。

在Java API文档中,对Buffer的说明摘入如下:

Buffer:是一个用于特定基本数据类型的容器。这里的特定基本数据类型指的是:除boolean类型的其他基本上数据类型。

缓冲区是特定基本数据类型元素的线性有限序列。除内容外,缓冲区饿基本属性还包括三个重要的属性,如下:

1、capacity(容量):表示Buffer容量的大小。

2、limit(限制):是第一个不应该读取或写入的元素的索引。缓冲区的限制不能为负数,并且不能大于其容量。

3、position(位置):表示下一个要读取或写入的元素的索引。缓冲区的位置不能为负数,并且不能大于其限制。

刚看文档的时候,可能对limit和position的含义不是太能理解。这个我们看完源码之后,就会懂了哈,不急。

不过在看源码之前,可以提前来通过画图的方式来解释下limit 和 position。

在Buffer中有两种模式,一种是写模式,一种是读模式。

有了上图应该比较好理解position和limit的含义了。

下面就看下Buffer的源代码了。由于Buffer有很多子类,这里主要以IntBuffer为例。

Buffer的几个重要属性

    // Invariants: mark <= position <= limit <= capacity
    private int mark = -1;
    private int position = 0;//位置
    private int limit;//限制
    private int capacity;//容量

这几个属性就也就是我们上面说到的position、limit、capacity,最后还有一个mark。

Buffer的构造方法

    //构造函数,根据指定的参数来初始化Buffer特定的属性
    //此构造函数时包私有的
    Buffer(int mark, int pos, int lim, int cap) {       // package-private
        if (cap < 0)
            throw new IllegalArgumentException("Negative capacity: " + cap);
        this.capacity = cap;
        limit(lim);
        position(pos);
        if (mark >= 0) {
            if (mark > pos)
                throw new IllegalArgumentException("mark > position: ("
                                                   + mark + " > " + pos + ")");
            this.mark = mark;
        }
    }

构造函数中的逻辑相当简单,就是一个初始化,不过在里面包括的相关的有效性检查。

要注意的是此构造函数是包私有的。

可能有人像我一样,会有这样一个疑问:Buffer类是抽象类,为什么会有构造函数呢?

由于关于抽象类中有构造函数,自己也是第一次见到。因此查阅的相关资料。发现如下:

1、抽象类是可以有构造函数的。但很多人认为,构造函数用于实例化一个对象(或建立一个对象的实例),而抽象类不能被实例化,所以抽象类不应该有公共的构造函数。但不应该有“公共”的构造函数,和不应该有构造函数,这是两个不同的概念,所以,如果抽象类需要构造函数,那么应该声明为“protected”。

2、既然抽象类是可以,甚至有时候应该有构造函数,那抽象类的构造函数的作用是什么?我觉得至少有两个:

(1)初始化抽象类的成员;

(2)为继承自它的子类使用。

在Buffer这个抽象类中我们可以明显的感受到以上两点的作用。

3、即使我们声明一个没有构造函数的抽象类,编译器还会为我们生成一个默认的保护级别的构造函数。子类实例化时(不管是否为带参构造)只会调用所有父类的无参构造函数,而带参构造必须通过显式去调用

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值