In most applications like this you'll see direct byte manipulation to byte buffers because you want to pull as much performance as possible.
There are fast serialization formats like SBE that people leverage for this as well.
Your transfer object needs to implement MemorySerializable. Below two examples from CoralRing's GitHub:
https://github.com/coralblocks/CoralRing/blob/main/src/main/...
The second one effectively allows you to send anything you want (as bytes) through the ring, making CoralRing message agnostic.
In most applications like this you'll see direct byte manipulation to byte buffers because you want to pull as much performance as possible.
There are fast serialization formats like SBE that people leverage for this as well.