readonlybufferexception 在尝试对只读缓冲区执行写操作时抛出,因 asreadonlybuffer() 等方法创建的缓冲区内部标记为不可写,调用 put、clear 等方法即触发该异常。
readonlybufferexception 是 java nio 中的一个运行时异常,当尝试对一个只读缓冲区(read-only buffer)执行写操作时抛出。它继承自 readonlybufferexception,属于 java.nio 包。
为什么会出现 ReadOnlyBufferException?
Java NIO 的缓冲区(如 ByteBuffer、CharBuffer 等)支持“只读视图”机制。调用 buffer.asReadOnlyBuffer() 会返回一个与原缓冲区共享数据但禁止修改的新缓冲区。这个只读缓冲区在内部标记为不可写,任何试图修改其内容的操作(如 put()、compact()、flip()、rewind()、clear() 等)都会触发该异常。
常见触发场景包括:
- 对
asReadOnlyBuffer()返回的缓冲区调用put(...) - 误将只读缓冲区传给期望可写缓冲区的工具方法
- 使用
wrap()包装了不可变数组(如 String 内部 char[])后又未注意是否只读 - 通过
duplicate()或slice()得到的缓冲区本身是只读的(若原缓冲区只读)
如何判断一个缓冲区是否只读?
所有 Buffer 子类都提供 isReadOnly() 方法,返回 boolean 值:
if (buffer.isReadOnly()) {
System.out.println("该缓冲区不可写");
}
建议在执行写操作前主动检查,尤其在接收外部传入的缓冲区参数时,避免盲目调用 put 类方法。
如何安全地写入只读缓冲区的数据?
不能直接修改只读缓冲区,但可以按需创建新的可写缓冲区来承载相同内容:
- 若原始数据来自可访问的数组:用
ByteBuffer.wrap(array.clone())或ByteBuffer.allocate(...).put(...)构造新缓冲区 - 若只有只读缓冲区引用且需保留其状态(position、limit等):先复制内容和元信息:
ByteBuffer writable = ByteBuffer.allocate(buffer.remaining()).put(buffer.duplicate()).flip(); - 若只需读取内容,就不要调用写方法——只读缓冲区完全支持
get()、hasRemaining()、toString()等读操作
设计建议:明确缓冲区所有权与意图
在 API 设计或团队协作中,应主动传达缓冲区的可变性:
- 方法参数命名可体现语义,如
readOnlyData、writableOutput - 文档或注释中说明是否接受只读缓冲区,例如:“本方法仅读取缓冲区,支持只读视图”
- 对外提供只读视图时,优先使用
asReadOnlyBuffer()而非简单暴露原始缓冲区,防止意外修改 - 避免在无必要时将缓冲区设为只读;若需保护数据,封装成不可变容器更清晰
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











