Java Byte Buffer行为

Ank*_*mar -2 java nio

我刚刚玩Java ByteBuffers并且不明白为什么输出不正确.

import java.nio.ByteBuffer;

public class TestBuffers {
    public static void main(String[] args) {
        ByteBuffer byteBuffer = ByteBuffer.allocate(100);
        byteBuffer.put((byte)'H').put((byte)'e').put((byte)'l').put((byte)'l');
        System.out.println(byteBuffer.asCharBuffer().toString()); // should print "Hell"
    }
}
Run Code Online (Sandbox Code Playgroud)

上面的程序应该打印"地狱",但事实并非如此.但如果我put()从1开始给出通话中的位置然后它有效,为什么呢?

Ole*_*hin 5

您的代码和处理该任务的方法存在一些问题:

  1. put()没有显式索引的方法将更新缓冲区位置.在四次放置操作之后,缓冲位置为4.
  2. asCharBuffer() 重复使用原始缓冲区的内容,从原始缓冲区中的当前位置开始,该位置为4,原始缓冲区没有从该位置开始的实际数据.
  3. flip()在尝试执行get一系列操作之后执行操作之前确实是正确的put操作,但是:
  4. 在Java中,char是一个双字节值,这意味着您的原始4字节缓冲区将被解释为2字符缓冲区,例如第一个字符的值将是( char ) ( ( ( ( byte ) 'H' ) << 8 ) + ( byte ) 'e' ).

除此之外,其ByteBuffer行为完全符合预期并记录在其javadoc中.

一个修复编码问题的例子:

ByteBuffer byteBuffer = ByteBuffer.allocate( 100 );
byteBuffer
        // explicitly converting each char into 2 bytes
        .put( ( byte ) ( 'H' >>> 8 ) ).put( ( byte ) 'H' ) 
        .put( ( byte ) ( 'e' >>> 8 ) ).put( ( byte ) 'e' )
        .put( ( byte ) ( 'l' >>> 8 ) ).put( ( byte ) 'l' )
        .put( ( byte ) ( 'l' >>> 8 ) ).put( ( byte ) 'l' )
        .put( ( byte ) ( 'o' >>> 8 ) ).put( ( byte ) 'o' );
// flipping the buffer to be able access the current content via get operations
byteBuffer.flip();
// reinterpreting the byte sequence as a char sequence
CharBuffer charBuffer = byteBuffer.asCharBuffer();
System.out.println( charBuffer.toString() );
Run Code Online (Sandbox Code Playgroud)