Java 自动字段值序列化

发布于 2025-01-06 07:44:13 字数 591 浏览 1 评论 0原文

假设我们有一个类似结构体的 java 类,

public class Person {
    private int height;
    private byte nChildren;
    private int  salary; 

    public byte[] serializeField() {
        ByteBuffer buf = ByteBuffer.allocate(4 + 1 + 4);
        buf.order(ByteOrder.BIG_ENDIAN);
        buf.putInt(height);
        buf.put(nChildren);
        buf.putInt(salary);
        return buf.array(); 
    }

    /*
     * setters and getters
     */
}

是否有一个库可以为任何给定的类自动执行 serializeField() 函数?它应该能够维护类中定义的字段的精确顺序,并且可能能够忽略某些字段(例如serialVersionUID)。

Lets say we have a struct-llike java class

public class Person {
    private int height;
    private byte nChildren;
    private int  salary; 

    public byte[] serializeField() {
        ByteBuffer buf = ByteBuffer.allocate(4 + 1 + 4);
        buf.order(ByteOrder.BIG_ENDIAN);
        buf.putInt(height);
        buf.put(nChildren);
        buf.putInt(salary);
        return buf.array(); 
    }

    /*
     * setters and getters
     */
}

Is there a library that can perform the serializeField() function automatically for any given class? It should be able to maintain the exact order of the fields as defined in the class and perhaps have the ability to ignore certain fields (like the serialVersionUID).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

枫林﹌晚霞¤ 2025-01-13 07:44:13

您可以使用反射来编写一个。

如果性能很重要,您可以

  • 传入一个 ByteBuffer 进行追加,以避免创建大量您丢弃的缓冲区。

    public void serializeField(ByteBuffer buf) {
        buf.putInt(高度);
        buf.put(nChildren);
        buf.putInt(工资);
    }
    
  • 并生成代码(使用反射等)以避免在运行时使用反射。即使用反射来生成上面或下一个示例中的代码。

  • 将字段 getter 和 setter 映射到 ByteBuffer,这样就不会发生序列化/反序列化。

假设您有一个具有宽度和高度的对象。正如您所看到的,这些值被更新到 ByteBuffer(例如直接文件或内存映射文件)中,这样就没有序列化开销。

class Sized {
    private ByteBuffer buffer;
    private static final int HEIGHT_OFFSET = 0;
    private static final int WIDTH_OFFSET = 4;

    public void setBuffer(ByteBuffer buffer) {this.buffer = buffer; }
    public int getHeight() { return buffer.getInt(HEIGHT_OFFSET); }
    public void setHeight(int height) { buffer.putInt(HEIGHT_OFFSET, height); }
    public int getWidth() { return buffer.getInt(WIDTH_OFFSET); }
    public void setWidth(int width) { buffer.putInt(WIDTH_OFFSET, width); }
}

要处理内存映射数据,您可以使用这样的库。

https://github.com/peter-lawrey/Java-Chronicle

这个库允许您创建任意数量的事件/记录(数十亿),这些事件/记录可以非常快速地更新(但写入后的大小不会增加)。例如每秒数百万条记录,延迟亚微秒。它还可以在进程之间共享。一旦超过主内存,主要限制是硬盘驱动器的速度(如果超过内存使用量)。也就是说,SSD 确实会有帮助。它有一种模式,您只需启用 Unsafe 类即可直接使用它(比 ByteBuffer 更低级别)。

You can write one using reflection.

If performance matters, you can

  • pass in a ByteBuffer to append to to avoid creating lots of buffers you discard.

    public void serializeField(ByteBuffer buf) {
        buf.putInt(height);
        buf.put(nChildren);
        buf.putInt(salary);
    }
    
  • and generate your code (using reflection etc) to avoid using reflection at runtime. i.e. use reflection to generate the code above or in the next example.

  • map the fields getters and setters into a ByteBuffer so there is no serialization/deserialization as such.

Say you have an object with a width and height. As you can see the values are updated into a ByteBuffer (e.g. a direct or memory mapped file) This way there is no serialization overhead as such.

class Sized {
    private ByteBuffer buffer;
    private static final int HEIGHT_OFFSET = 0;
    private static final int WIDTH_OFFSET = 4;

    public void setBuffer(ByteBuffer buffer) {this.buffer = buffer; }
    public int getHeight() { return buffer.getInt(HEIGHT_OFFSET); }
    public void setHeight(int height) { buffer.putInt(HEIGHT_OFFSET, height); }
    public int getWidth() { return buffer.getInt(WIDTH_OFFSET); }
    public void setWidth(int width) { buffer.putInt(WIDTH_OFFSET, width); }
}

To handle the memory mapped data you can use a library like this.

https://github.com/peter-lawrey/Java-Chronicle

This library allow you to create any number of events/records (billions) which can be updated (but not grown in size once written) very quickly. e.g. millions of records per second with sub-microsecond latency. It can also be shared between processes. Once you exceed your main memory, the main limitation is the speed of your hard drive if you exceed your memory usage. i.e. an SSD will really help. It has a mode where you use the Unsafe class directly (more low level than ByteBuffer) by just enabling it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文