No, this does not exist, and cannot exist without violating the contract of ByteBuffer's superclass Buffer:
A buffer is a linear, finite sequence of elements of a specific primitive type. Aside from its content, the essential properties of a buffer are its capacity, limit, and position:
- A buffer's capacity is the number of elements it contains. The capacity of a buffer is never negative and never changes.
Therefore, if you were to allow "seamless dynamic growing", ByteBuffer would no longer act as a Buffer. This is also true regardless of interfaces versus abstract classes: Neither subclasses nor interface implementations should break invariants defined in the classes they extend. After all, consumers of your HypotheticalGrowingByteBuffer might rely on Buffer's fixed capacity to cache a single call to capacity()
, which otherwise would be defined not to change.
Another motivating factor behind making ByteBuffer an abstract class rather than an interface: The memory backing the buffer is defined to be necessarily fixed and contiguous, which allows for higher performance than a more flexible definition.
That said, Buffer defines a mutable concept of limit
, where a large originally-allocated buffer might have its availability artificially constrained. You can use this to constrain a large buffer to start small and then grow, though the growing will not be "seamless"; it will be limited by the original buffer capacity you define. If the goal is simply to concatenate smaller fixed-size buffers where the overall total size is predictable, it may be worthwhile to generate them as pieces of a larger buffer using ByteBuffer.duplicate and setting the mark and limit to constrain the writable area.