简体   繁体   English

我怎样才能将ByteBuffer子类化?

[英]how can I subclass ByteBuffer?

So the Java NIO architects didn't make a ByteBuffer interface, but rather a ByteBuffer class , which isn't a final class, but it has no package-public constructors, and therefore it can't be subclassed outside of its package. 所以Java NIO架构师没有创建ByteBuffer接口,而是ByteBuffer ,它不是最终类,但它没有包 - 公共构造函数,因此它不能在其包之外进行子类化。 Phooey. 阿福。 :P :P

I have a program that uses memory-mapped file byte buffers (obtained via FileChannel.map()) in a bunch of places, and I'm trying to track down a nasty bug where the file in question is left open because there is at least one ByteBuffer that isn't released to garbage collection. 我有一个程序使用内存映射文件字节缓冲区(通过FileChannel.map()获得)在一堆地方,我正在尝试追踪一个讨厌的错误,有问题的文件是打开的,因为有at至少一个没有发布到垃圾收集的ByteBuffer

I would like to create an InstrumentedByteBuffer class that looks like a byte buffer, but decorates a regular ByteBuffer (or its subclasses eg MappedByteBuffer ) and keeps track of its existence (including new buffers created by duplicate() and slice() ) -- that way I can keep my code intact that uses the ByteBuffer, I just have to decorate the original byte buffer. 创建一个InstrumentedByteBuffer类,看起来像一个字节的缓冲区,但装饰定期ByteBuffer (或它的子类,例如MappedByteBuffer ),并保持它的存在(包括创建新的缓冲区的赛道duplicate()slice() -即我可以保持我的代码完整,使用ByteBuffer,我只需要装饰原始的字节缓冲区。

Is there any way to do this (via reflection or proxies or whatever) to get around the private constructors? 有没有办法做到这一点(通过反射或代理或其他)来绕过私人构造函数? I don't need to ship this into a final product, I just need to use it temporarily to solve this bug. 我不需要将它发送到最终产品,我只需要暂时使用它来解决这个bug。

I'm trying to track down a nasty bug where the file in question is left open because there is at least one ByteBuffer that isn't released to garbage collection 我正在尝试追踪一个令人讨厌的错误,其中有问题的文件保持打开状态,因为至少有一个未发布到垃圾收集的ByteBuffer

That doesn't make sense. 这没有意义。 An uncollected ByteBuffer won't stop a file being closed. 未收集的ByteBuffer不会停止文件被关闭。 You're barking up the wrong tree here. 你在这里咆哮着错误的树。 However there is a well-known problem with MappedByteBuffer whereby it is never garbage-collected, keeping the file effectively open. 然而, MappedByteBuffer存在一个众所周知的问题,即永远不会被垃圾收集,从而使文件保持有效打开状态。 It's really a design problem: it has been known about for years but there is no real solution. 这确实是一个设计问题:多年来人们都知道它,但没有真正的解决方案。 The moral is don't use large numbers of MappedByteBuffers . 道德是不要使用大量的MappedByteBuffers

JMockit provides a convenient way of creating a mocked class. JMockit提供了一种创建模拟类的便捷方法。 It may be of help in this case. 在这种情况下它可能会有所帮助。

Mock the methods you are interested in, and let them do your bookkeeping and then call the original class' method . 模拟你感兴趣的方法,让他们做你的簿记, 然后调用原始类的方法

I think you are on the wrong track. 我认为你走错了路。 FileChannel.map() is broken by design because its limited to 2GB chunks and you can't control when the mapping should get picked up by the garbage collection. FileChannel.map()被设计破坏,因为它限制为2GB块,并且您无法控制何时应该通过垃圾收集拾取映射。 On Windows, this is a frequent cause for the application not being able to open the mapped file again. 在Windows上,这是应用程序无法再次打开映射文件的常见原因。

So instead of making things even worse with byte code instruction or similar hacks, you should refactor your code to get rid of FileChannel.map(). 因此,不要使用字节码指令或类似的黑客更糟糕,你应该重构你的代码以摆脱FileChannel.map()。 The next programmer who has to maintain your code will be very thankful if you did. 如果你做的话,下一个必须维护代码的程序员将非常感激。 ;-) ;-)

I don't see why you need to subclass here. 我不明白为什么你需要在这里继承。 Why not use AOP? 为什么不使用AOP? AspectJ seems perfect for the job. AspectJ似乎非常适合这项工作。 If you're really feeling ambitious, use Java Instrumentation and do some byte code engineering :P 如果您真的有野心,请使用Java Instrumentation并进行一些字节码工程:P

Hmm -- I just ran across this: the JavaSpecialists newsletter 168 seems like it can produce a general-purpose delegation framework -- if a bit slow due to reflection. 嗯 - 我刚刚遇到过这个问题: JavaSpecialists通讯168似乎可以产生一个通用的委托框架 - 如果由于反射有点慢。

Socket uses the strategy pattern for the actual communication and we are able to specify our own implementation. Socket使用策略模式进行实际通信,我们可以指定自己的实现。 Thus all we would need to do is write our own strategy that counts the bytes flowing backwards and forwards. 因此,我们需要做的就是编写自己的策略来计算向后和向前流动的字节数。 Unfortunately the standard strategy implementations are package access in the java.net.* package, so we are not able to use them directly. 不幸的是,标准策略实现是java.net。*包中的包访问,因此我们无法直接使用它们。 We certainly cannot subclass them, but we could call the methods with reflection. 我们当然不能将它们子类化,但我们可以用反射来调用这些方法。 However, because the classes themselves are package access, we need to find the declared constructor, set that to be accessible and then instantiate it. 但是,因为类本身是包访问,所以我们需要找到声明的构造函数,将其设置为可访问,然后实例化它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM