readonlybufferexception在对只读缓冲区调用put、compact、flip等修改状态或内容的方法时抛出;因asreadonlybuffer()创建的缓冲区禁止所有写操作,包括改变position/limit的flip/rewind/clear,需用isreadonly()预检并创建可写副本处理。

ReadOnlyBufferException 是 Java NIO 中的一个非受检异常(RuntimeException 子类),在尝试对只读缓冲区(read-only buffer)执行写操作时抛出。
为什么会出现 ReadOnlyBufferException
当调用 ByteBuffer.asReadOnlyBuffer()、CharBuffer.asReadOnlyBuffer() 等方法创建只读视图后,该缓冲区的所有写入方法(如 put()、compact()、flip()、rewind()、clear())都会被禁止。一旦调用,JVM 就会立即抛出 ReadOnlyBufferException。
注意:flip()、rewind()、clear() 虽不修改内容,但会修改位置(position)、限制(limit)等状态字段,因此也被视为“写操作”而受限。
常见触发场景
- 对
asReadOnlyBuffer()返回的缓冲区调用put(byte)或put(byte[]) - 误将只读缓冲区传给期望可写缓冲区的工具方法(例如自定义的序列化/填充逻辑)
- 调用
duplicate()后未检查原缓冲区是否只读 ——duplicate()会继承只读属性 - 使用
slice()得到子缓冲区,而原缓冲区是只读的 —— 子缓冲区也自动为只读
如何安全处理只读缓冲区
可通过 isReadOnly() 方法提前判断:
if (buffer.isReadOnly()) {
// 不执行 put / compact / clear 等写操作
// 可选择复制一份可写副本:ByteBuffer.allocate(buffer.remaining()).put(buffer).flip();
}
若需修改数据,应显式创建可写副本:
- 用
ByteBuffer.allocate(n).put(srcReadOnlyBuffer).flip()复制内容 - 或用
srcReadOnlyBuffer.duplicate().asReadOnlyBuffer()是无效的 —— 仍是只读;正确做法是先duplicate()再确保源非只读,否则只能重新分配并拷贝
设计建议
对外暴露缓冲区时,若不希望调用方修改内容,优先使用 asReadOnlyBuffer();接收缓冲区参数的方法中,如需写入,应在文档或运行时校验 !buffer.isReadOnly() 并给出明确提示。
不复杂但容易忽略
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











