Buffer是Java NIO中最基本的概念,也是java.nio包中的最基礎的類(lèi)?!?a >Java NIO》書(shū)中對Buffer的描述是“a holding tank, or staging area”,而在《Thinking in Java》則把Buffer比作穿梭于礦井和外部之間的,運載礦物的貨車(chē)。實(shí)際上,在Java NIO中的設計更為接近操作系統底層的實(shí)際運作,運用Buffer也是為了提高IO效率,這篇我們就來(lái)看下Buffer相關(guān)的最基本的內容。
0. Buffer
Buffer是Java API在java.nio包中的第一個(gè)類(lèi),而java.nio包中的類(lèi)大部分都是Buffer的子類(lèi)。Buffer類(lèi)本身是抽象的,甚至連put()、get()方法都沒(méi)有給出,它主要有這樣一些直接子類(lèi),分別和非布爾的基本類(lèi)型對應: ByteBuffer, CharBuffer, DoubleBuffer, FloatBuffer, IntBuffer, LongBuffer, ShortBuffer。
再來(lái)看JDK中Buffer類(lèi)的實(shí)現,是圍繞對應于Buffer的一個(gè)數組展開(kāi)的,Buffer類(lèi)中給出了如下4個(gè)屬性變量:
另外,這4個(gè)屬性變量中前后每?jì)蓚€(gè)都恒有<=關(guān)系。
和這4個(gè)屬性對應,Buffer中還提供了一些相關(guān)的方法:
有意思的是,上述方法大部分都是返回Buffer類(lèi)型的,即Buffer對象本身,可以用來(lái)連續做實(shí)例方法調用。
此外,Buffer中有array()和arrayOffset()方法,但是是抽象的未實(shí)現的方法。
還有address屬性,按注釋說(shuō)明,是Direct Buffer才會(huì )用到。
1. CharBuffer等其他基本類(lèi)型對應的Buffer子類(lèi)
關(guān)于Buffer的子類(lèi),我們可以看如下圖。
我們看到這些直接子類(lèi)都有A標記,也就是說(shuō)它們都是抽象類(lèi)。
這些類(lèi)的具體實(shí)現都是Java API之外的,往往都和具體的平臺底層結構有關(guān),它們封裝了如字節序處理相關(guān)等內容。但對于上述這些Buffer子類(lèi),我們通常不必關(guān)心其具體實(shí)現。我們只需要通過(guò)allocate()和wrap()方法來(lái)分配或者初始化即可。
allocate()和wrap()都是靜態(tài)方法,在Buffer的子類(lèi)中有實(shí)現。其中allocate()是新分配,而wrap()則可以通過(guò)實(shí)現實(shí)例化的數組作為Buffer的數據存儲支持。其中ByteBuffer還有allocateDirect()方法,這個(gè)后面的文章詳細說(shuō)明。
對應地,子類(lèi)也都給出了Buffer類(lèi)中array()和arrayOffset()的具體實(shí)現,在Buffer使用堆中的數組支持的并且非只讀情況下,會(huì )分別返回數組和偏移量。有hasArray()方法判斷前兩者的可用性。
還有,最基本地,這些Buffer的直接子類(lèi)也都給出了各種重載的put()和get()方法,但是是抽象的,具體實(shí)現在這些Buffer直接子類(lèi)的具體子類(lèi)中實(shí)現。如用堆中數組作為數據支持的實(shí)現中,put()和get()則分別是對數組進(jìn)行存取操作。
除了上面所說(shuō)的,這些子類(lèi)也基本都提供了這樣幾個(gè)方法:
其它的就是個(gè)子類(lèi)結合類(lèi)型的情況和實(shí)現不同的接口提供的方法了,如CharBuffer實(shí)現了Appendable接口,有append()方法等。
2. 其它
上面已經(jīng)對Buffer和Buffer各子類(lèi)通用的最基本的內容做了闡述。而在JDK實(shí)現上不同平臺有所不同,這個(gè)就不做細節介紹了,可以參見(jiàn)對應平臺的JDK源碼。
而B(niǎo)yteBuffer是直接對應字節處理的,比較特殊。關(guān)于ByteBuffer的特征,后文會(huì )詳細整理。
聯(lián)系客服