如何避免制作 ByteBuffer 的防御性副本?
我有一个类,它采用 ByteBuffer 作为构造函数参数。有没有办法避免制作防御性副本,以确保缓冲区不会在该点之后被修改?
ByteBuffer.isReadOnly() 不保证原始所有者不会修改缓冲区。更糟糕的是,似乎没有办法子类化 ByteBuffer。有什么想法吗?
I've got a class that takes a ByteBuffer as a constructor argument. Is there a way to avoid making defensive copies in order to ensure that the buffer doesn't get modified past that point?
ByteBuffer.isReadOnly() doesn't guarantee that the original owner won't modifying the buffer. To make matters worse, there doesn't seem to be a way to subclass ByteBuffer. Any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
正如您所说,唯一真正的方法是 buf.asReadOnlyBuffer(),然后将其传递到构造函数中。除此之外没有其他选择,尽管您可以将内容复制到新的 ByteBuffer 中,然后将其传递。
The only real way is, as you say,
buf.asReadOnlyBuffer()
, then pass this into the constructor. There's no other option apart from this, although you could do a copy of the contents into a newByteBuffer
, then pass that.这是我目前能做的最好的事情:
我还向 Oracle 提交了功能请求: https://bugs.java.com/bugdatabase/view_bug?bug_id=7130631
This is the best I could do for now:
I've also filed a feature request with Oracle: https://bugs.java.com/bugdatabase/view_bug?bug_id=7130631
不避免复制,但也许:
作者类的构造函数允许传入的“副本”
ByteBuffer,但让类使用池中的 ByteBuffer 进行移动
应用程序启动/关闭的分配/释放成本。这样只需要支付内存复制成本。
Doesn't avoid a copy, but perhaps:
constructor of Author's class to allow a 'copy' of incoming
ByteBuffer, but have class use a ByteBuffer from the pool to move
Alloc/Dealloc costs to app startup/shutdown. Only pay a memcopy cost this way.
这并不能完全回答问题,但是,对于某些用途(例如,如果您主要试图强制执行“按合同设计”),它可能足够好并且更高效。对于其他用途,它将不起作用并且效率可能会低得多。
在构造函数期间,保存 ByteBuffer 的 hashCode
Final int OriginalBBHashCode = byteBuffer.hashCode();
然后,在代码中要验证 ByteBuffer 是否未更改的几个关键位置,验证 byteBuffer.hashCode() == OriginalBBHashCode。如果不是,则抛出异常。坦率地说,我很想抛出 ConcurrentModificationException,因为这是您正在模仿的行为,但是 YMMV。
This doesn't quite answer the question, but, for some usages (e.g. if you are mainly trying to enforce "design by contract") it may be good enough and more efficient. For other usages it will not work and may be far less efficient.
During your constructor, save away the hashCode of the ByteBuffer
final int originalBBHashCode = byteBuffer.hashCode();
Then, at the few critical places in your code where you want to verify that the ByteBuffer hasn't changed, verify that the byteBuffer.hashCode() == originalBBHashCode. If not, throw an exception. Frankly, I'd be tempted to throw a ConcurrentModificationException, since that is the behavior you are mimicking, but YMMV.